home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d12 / v10n19.arc / PATCH.ARC / PATCH.ASM < prev    next >
Assembly Source File  |  1991-10-24  |  150KB  |  4,676 lines

  1. ;--------------------------------------------------------------------;
  2. ;  PATCH * Michael J. Mefford                                        ;
  3. ;                                                                    ;
  4. ;  Program customizer                                                ;
  5. ;--------------------------------------------------------------------;
  6.  
  7. _TEXT          SEGMENT PUBLIC 'CODE'
  8.                ASSUME  CS:_TEXT,DS:_TEXT,ES:_TEXT,SS:_TEXT
  9.  
  10.                ORG     100H
  11. START:         JMP     MAIN
  12.  
  13. ;              DATA AREA
  14. ;              ---------
  15. COLOR_ATTRIBS  STRUC
  16. B              DB      71H                     ;Blue on lt. gray  ;Menu
  17. W              DB      17H                     ;Lt. gray on blue  ;Inactive window
  18. C              DB      31H                     ;Blue on cyan      ;Active bar
  19. I              DB      1FH                     ;White on blue     ;Active window
  20. A              DB      07H                     ;Lt. gray on black ;Inactive bar
  21. S              DB      10H                     ;Black on blue     ;Unavailable entry
  22. T              DB      01H                     ;Blue on black     ;Unavailable bar
  23. COLOR_ATTRIBS  ENDS
  24.  
  25. COLOR          COLOR_ATTRIBS  <>
  26.  
  27. COLOR_ATTR     COLOR_ATTRIBS  <>
  28. MONO_ATTR      COLOR_ATTRIBS  <70H, 07H, 70H, 0FH, 70H, 00H, 00H>
  29.  
  30. BORDER_FLAG    DB      0                       ; =1 to disable.
  31. XMODEM_FLAG    DB      FALSE                   ; =1 to disable file size check.
  32.  
  33. COPYRIGHT      DB      "PATCH 1.0 Copyright (c) 1991 Michael J. Mefford",CR,LF
  34. FIRST_RIGHTS   DB      "First Published in PC Magazine, November 12, 1991",CR,LF,LF
  35.  
  36. SYNTAX LABEL BYTE
  37. DB  "Syntax: PATCH [.ZIF directory] [program directory]",CR,LF,LF
  38.  
  39. DB  "$"
  40.  
  41. TAB            EQU     9
  42. CR             EQU     13
  43. LF             EQU     10
  44. CTRL_Z         EQU     26
  45. SPACE          EQU     32
  46. BOX            EQU     254
  47. FF             EQU     12
  48. SINGLE_QUOTES  EQU     44
  49. DOUBLE_QUOTES  EQU     34
  50. SHIFT_KEYS     EQU     00000011B
  51. RIGHT_SHIFT    EQU     00000001B
  52. LEFT_SHIFT     EQU     00000010B
  53. CTRL_KEY       EQU     00000100B
  54. ALT_KEY        EQU     00001000B
  55. ESC_SCAN       EQU     01H
  56. Y_SCAN         EQU     15H
  57. N_SCAN         EQU     31H
  58. F1_SCAN        EQU     3BH
  59. F2_SCAN        EQU     3CH
  60. F3_SCAN        EQU     3DH
  61. F4_SCAN        EQU     3EH
  62. F5_SCAN        EQU     3FH
  63. F6_SCAN        EQU     40H
  64. F7_SCAN        EQU     41H
  65. F8_SCAN        EQU     42H
  66. F9_SCAN        EQU     43H
  67. F10_SCAN       EQU     44H
  68. KB_FLAG        EQU     17H
  69. UP_SCAN        EQU     48H
  70. DOWN_SCAN      EQU     50H
  71. LEFT_SCAN      EQU     4BH
  72. RIGHT_SCAN     EQU     4DH
  73. PGUP_SCAN      EQU     49H
  74. PGDN_SCAN      EQU     51H
  75. BS_SCAN        EQU     0EH
  76. DEL_SCAN       EQU     53H
  77. HOME_SCAN      EQU     47H
  78. END_SCAN       EQU     4FH
  79. ENTER_SCAN     EQU     1CH
  80. TAB_SCAN       EQU     0FH
  81. CTRL_HOME_SCAN EQU     77H
  82. CTRL_END_SCAN  EQU     75H
  83. PLUS1_SCAN     EQU     0DH
  84. PLUS2_SCAN     EQU     4EH
  85. MINUS1_SCAN    EQU     0CH
  86. MINUS2_SCAN    EQU     4AH
  87. SHIFT_F4       EQU     57H
  88. SHIFT_F5       EQU     58H
  89. SHIFT_F6       EQU     59H
  90. SHIFT_F9       EQU     5CH
  91. SHIFT_F10      EQU     5DH
  92. CTRL_F2        EQU     5FH
  93. ALT_F1         EQU     68H
  94. SPACE_SCAN     EQU     39H
  95.  
  96. LEFT_ARROW     EQU     27
  97. RIGHT_ARROW    EQU     26
  98. UP_ARROW       EQU     24
  99. DOWN_ARROW     EQU     25
  100. COMMA          EQU     ","
  101. DECIMAL_POINT  EQU     "."
  102. PLUS_SIGN      EQU     "+"
  103. MINUS_SIGN     EQU     "-"
  104. NOTE           EQU     1046                    ; C
  105.  
  106. PORT_A         EQU     60H
  107.  
  108. TRUE           EQU     1
  109. FALSE          EQU     0
  110. FILE_CURRENT   DB      FALSE
  111. LISTING_TYPE   EQU     0
  112. FILE_TYPE      EQU     1
  113. CUSTOM_TYPE    EQU     2
  114. SELECT_TYPE    EQU     3
  115. STATE          DB      LISTING_TYPE
  116.  
  117. DOS_VERSION    DW      ?
  118. SCREEN_COLOR   DB      ?
  119. BREAK          DB      ?
  120.  
  121. DEFAULT_DRIVE  DB      ?
  122. CURRENT_DIR    DB      66 DUP (?)
  123. ZIF_DRIVE      DB      ?
  124. ZIF_DIR        DB      66 DUP (?)
  125. SPEC_SIZE      EQU     $ - ZIF_DRIVE
  126. PGM_DRIVE      DB      ?
  127. PGM_DIR        DB      66 DUP (?)
  128.  
  129. MATCHING       STRUC
  130. RESERVED       DB      21 DUP (?)
  131. ATTRIBUTE      DB              ?
  132. FILE_TIME      DW              ?
  133. FILE_DATE      DW              ?
  134. SIZE_LOW       DW              ?
  135. SIZE_HIGH      DW              ?
  136. FILE_NAME      DB      13 DUP (?)
  137. MATCHING       ENDS
  138.  
  139. FILE_RECORD    STRUC
  140. LIST_NAME      DB      12 DUP (?)
  141. FILE_RECORD    ENDS
  142.  
  143. KILOBYTES      =       1024
  144. PARAGRAPH      =       16
  145. FILENAME_SIZE  =       64                      ;64K
  146. ZIF_BUFF_SIZE  =       64                      ;64K
  147. PGM_BUFF_SIZE  =       64                      ;64K
  148. BAC_BUFF_SIZE  =       64                      ;64K
  149. FILENAME_SEG   DW      ?
  150. ZIF_BUFF_SEG   DW      ?
  151. PGM_BUFF_SEG   DW      ?
  152. BAC_BUFF_SEG   DW      ?
  153.  
  154. BUFFER_SIZES   EQU     (FILENAME_SIZE+ZIF_BUFF_SIZE+PGM_BUFF_SIZE+BAC_BUFF_SIZE) * (KILOBYTES/PARAGRAPH)
  155.  
  156. TEMP_RECORD    EQU     FILENAME_SIZE * KILOBYTES - SIZE FILE_RECORD
  157.  
  158. DTA            DB      SIZE MATCHING DUP (?)
  159. ASCIIZ_NAME    DB      13 DUP (?)              ;ASCIIZ name.
  160. BACKUP_NAME    DB      13 DUP (?)
  161.  
  162. FAIL_FLAG      DB      FALSE                   ;True if open failed.
  163. ROW            DW      0
  164.  
  165. CRT_MODE       EQU     49H
  166. CRT_COLS       EQU     4AH
  167. CRT_ROWS       EQU     84H
  168. COLUMNS        DW      ?
  169. CRT_WIDTH      DW      ?
  170. CRT_START      DW      ?
  171. STATUS_REG     DW      3BAH
  172. VIDEO_SEG      DW      0B000H
  173. ROWS           DB      24
  174.  
  175. LISTING_TOP    EQU     5
  176. MENU_LINES     EQU     6
  177. CUSTOM_START   EQU     (SIZE FILE_RECORD + 1) * 2
  178. COLOR_TOP      EQU     LISTING_TOP
  179. SELECT_START   EQU     CUSTOM_START + ((CAT_NUL - CAT_TEXT + 2) * 2)
  180. HOT_TOP        EQU     LISTING_TOP + 1
  181. COM_TOP        EQU     LISTING_TOP + 2
  182. LPT_TOP        EQU     LISTING_TOP + 3
  183. TEXT_TOP       EQU     LISTING_TOP + 4
  184. NUMBER_TOP     EQU     LISTING_TOP + 5
  185. PICK_TOP       EQU     LISTING_TOP + 6
  186. WINDOW_TOP     EQU     24 / 2
  187.  
  188. LISTING_LEN    DW      ?
  189. LISTING_ADDR   DW      0
  190. BAR_ADDR       DW      0
  191. LAST_ADDR      DW      ?
  192.  
  193. FILENAME       DW      ?                       ;Address of filespec to parse.
  194. ZIF_BYTES      DW      ?
  195. PGM_BYTES      DW      ?
  196. FILE_CNT       DW      0
  197.  
  198. MODIFY_FLAG    DB      FALSE
  199.  
  200. LISTING_MENU   LABEL   BYTE
  201. DB "Select Utility then press Enter to select custom category.           Esc to Exit",0
  202.  
  203. CUSTOM_MENU    LABEL   BYTE
  204. DB "Select custom category then press Enter to customize.                Esc to Exit",0
  205.  
  206. STAR_DOT_ZIF   DB      "*"
  207. ZIF_EXT        DB      ".ZIF",0
  208. ZIF_LEN        EQU     $ - ZIF_EXT
  209. NONE_FOUND     DB      "No .ZIF files were found",CR,LF,LF,"$"
  210. NOT_ENOUGH     DB      "Not enough memory",CR,LF,LF,"$"
  211. CRLFLF         DB       CR,LF,LF,"$"
  212.  
  213. ;              CODE AREA
  214. ;              ---------
  215. KBD_STATUS     DB      ?
  216.  
  217. INT_9          PROC    NEAR
  218.  
  219.                PUSH    AX
  220.                IN      AL,PORT_A
  221.                CMP     AL,0E0H
  222.                JZ      INT_9_END
  223.                CMP     AL,0E1H
  224.                JZ      INT_9_END
  225.                MOV     CS:KBD_STATUS,AL
  226.  
  227. INT_9_END:     POP     AX
  228.                JMP     DWORD PTR CS:OLD9
  229.  
  230. INT_9          ENDP
  231.  
  232. ;----------------------------------------------;
  233. INT_24         PROC    NEAR
  234.  
  235.                STI
  236.                PUSHF
  237.                MOV     CS:FAIL_FLAG,TRUE
  238.                MOV     AL,3
  239.                CMP     CS:DOS_VERSION,300H
  240.                JAE     INT_24_END
  241.                XOR     AL,AL
  242. INT_24_END:    POPF
  243.                IRET
  244.  
  245. INT_24         ENDP
  246.  
  247. ;----------------------------------------------;
  248.  
  249. MAIN           PROC    NEAR
  250.                CLD
  251.  
  252.                MOV     AH,30H
  253.                INT     21H
  254.                XCHG    AL,AH
  255.                MOV     DOS_VERSION,AX
  256.  
  257.                CALL    INSTALL_9
  258.                CALL    INSTALL_24
  259.  
  260.                XOR     BH,BH
  261.                MOV     AH,8
  262.                INT     10H
  263.                MOV     SCREEN_COLOR,AH
  264.  
  265.                MOV     AX,3300H                ;Get Ctrl-Break state.
  266.                INT     21H
  267.                MOV     BREAK,DL
  268.  
  269.                XOR     DL,DL
  270.                MOV     AX,3301H
  271.                INT     21H
  272.  
  273.                MOV     AH,19H                  ;Get default drive so can
  274.                INT     21H                     ; restore after we change it.
  275.                MOV     DEFAULT_DRIVE,AL
  276.  
  277.                MOV     BX,OFFSET STACK_POINTER + 15
  278.                MOV     CL,4
  279.                SHR     BX,CL
  280.                ADD     BX,BUFFER_SIZES
  281.                MOV     AH,4AH                  ;Allocate memory.
  282.                INT     21H
  283.                JNC     SETUP_STACK
  284.                MOV     DX,OFFSET NOT_ENOUGH
  285.                JMP     ERROR_EXIT              ;If not enough, exit.
  286.  
  287. SETUP_STACK:   MOV     AX,OFFSET STACK_POINTER
  288.                MOV     SP,AX                   ;Set up stack.
  289.                ADD     AX,15
  290.                MOV     CL,4
  291.                SHR     AX,CL
  292.                MOV     CX,DS
  293.                ADD     AX,CX
  294.                MOV     FILENAME_SEG,AX         ;And data segments.
  295.                ADD     AX,FILENAME_SIZE * (KILOBYTES / PARAGRAPH)
  296.                MOV     ZIF_BUFF_SEG,AX
  297.                ADD     AX,ZIF_BUFF_SIZE * (KILOBYTES / PARAGRAPH)
  298.                MOV     PGM_BUFF_SEG,AX
  299.                ADD     AX,BAC_BUFF_SIZE * (KILOBYTES / PARAGRAPH)
  300.                MOV     BAC_BUFF_SEG,AX
  301.  
  302.                MOV     DX,OFFSET DTA
  303.                MOV     AH,1AH
  304.                INT     21H
  305.  
  306.                CALL    PARSE
  307.                CALL    FIND_FILES
  308.                MOV     DX,OFFSET NONE_FOUND
  309.                CMP     FILE_CNT,0
  310.                JZ      ERROR_EXIT
  311.                CALL    VIDEO_SETUP
  312.                CALL    HIDE_CURSOR
  313.                CALL    DISP_DIR
  314.                MOV     SI,OFFSET LISTING_MENU
  315.                CALL    DISPLAY_MENU
  316.                CALL    DISP_LISTING
  317.                CALL    DISP_FILE
  318.                JMP     SHORT NEXT_KEY
  319.  
  320. ;************* Main Loop *************;
  321.  
  322. NEXT_KEY:      CALL    GETKEY
  323.                JC      GOOD_EXIT
  324.                CMP     AL,RIGHT_SCAN
  325.                JZ      ENTER1
  326.                CMP     AH,CR
  327.                JNZ     CK_SPACE
  328.  
  329. ENTER1:        CALL    FILE
  330.                MOV     STATE,LISTING_TYPE
  331.                CALL    DISP_LISTING
  332.                CALL    DISP_FILE
  333.                MOV     SI,OFFSET LISTING_MENU
  334.                CALL    DISPLAY_MENU
  335.                JMP     NEXT_KEY
  336.  
  337. CK_SPACE:      CMP     AH,SPACE
  338.                JBE     MAIN_DISPATCH
  339.                CALL    SEARCH
  340.                JMP     NEXT_KEY
  341.  
  342. MAIN_DISPATCH: MOV     DI,OFFSET L_DISPATCH
  343.                MOV     CX,L_LEN
  344.                CALL    DISPATCH
  345.                CALL    DISP_LISTING
  346.                JMP     NEXT_KEY
  347.  
  348. ;----------------------------------------------;
  349.  
  350. ERROR_EXIT:    CALL    PRINT_STRING
  351.                MOV     AL,1
  352.                JMP     SHORT EXIT
  353.  
  354. GOOD_EXIT:     CALL    CLOSE_SCREEN
  355.                XOR     AL,AL                   ;EL=0.
  356.  
  357. EXIT:          PUSH    AX
  358.                CALL    UNINSTALL_9
  359.                CALL    RESTORE_DIR
  360.  
  361.                MOV     DL,BREAK
  362.                MOV     AX,3301H
  363.                INT     21H
  364.  
  365. TERMINATE:     MOV     DX,OFFSET COPYRIGHT
  366.                CALL    PRINT_STRING
  367.                POP     AX
  368.                MOV     AH,4CH
  369.                INT     21H
  370.  
  371. MAIN           ENDP
  372.  
  373.  
  374. ;**************
  375. ; SUBROUTINES *
  376. ;**************
  377. BACKUP_FLAG    DB      ?                       ;=TRUE if backup made.
  378.  
  379. FILE:          MOV     BACKUP_FLAG,FALSE
  380.                CMP     FILE_CURRENT,TRUE
  381.                JZ      DO_FILE2
  382.                JMP     FILE_END
  383.  
  384. DO_FILE2:      CALL    SET_PGM
  385.                CALL    MAKE_FILENAME
  386.  
  387. DO_FILE3:      MOV     DX,OFFSET ASCIIZ_NAME
  388.                XOR     CX,CX
  389.                MOV     AH,4EH
  390.                INT     21H
  391.                JNC     READ_FILE
  392.  
  393.                CALL    NEW_PGM
  394.                JNC     DO_FILE3
  395.                JMP     FILE_END
  396.  
  397. READ_FILE:     CALL    READ_PGM
  398.                JNC     CK_SIZE
  399.                JMP     FILE_ERR
  400.  
  401. CK_SIZE:       MOV     AX,DTA.SIZE_LOW
  402.                MOV     CX,DTA.SIZE_HIGH
  403.                MOV     BX,FILE_SIZE[0]
  404.                CMP     AX,BX
  405.                JNZ     CK_MODEM
  406.                CMP     CX,FILE_SIZE[2]
  407.                JZ      DO_FILE
  408.  
  409. CK_MODEM:      CMP     XMODEM_FLAG,TRUE
  410.                JZ      DO_FILE
  411.                ADD     BX,7FH                  ;128-1
  412.                AND     BX,NOT 7FH              ;Round up.
  413.                CMP     AX,BX
  414.                JNZ     WRONG_SIZE
  415.  
  416.                MOV     SI,FILE_SIZE
  417.                PUSH    DS
  418.                MOV     DS,PGM_BUFF_SEG
  419.                CMP     BYTE PTR [SI],0
  420.                POP     DS
  421.                JNZ     WRONG_SIZE
  422.  
  423. XMODEM:        CALL    DO_XMODEM
  424.                JC      FILE_END
  425.  
  426. DO_FILE:       MOV     STATE,FILE_TYPE
  427.                CALL    DISP_LISTING
  428. NEXT_FILE:     MOV     SI,OFFSET CUSTOM_MENU
  429.                CALL    DISPLAY_MENU
  430.                CALL    DISP_FILE
  431.  
  432. NEXT_FILE2:    CALL    GETKEY
  433.                JC      FILE_END
  434.                CMP     AL,LEFT_SCAN
  435.                JZ      FILE_END
  436.                MOV     BX,CUSTOM_ADDR
  437.                CMP     AH,CR
  438.                JZ      DO_MENU2
  439.                CMP     AL,RIGHT_SCAN
  440.                JZ      DO_MENU2
  441.  
  442.                CMP     AL,UP_SCAN
  443.                JNZ     CK_DOWN
  444.                CMP     BX,OFFSET CATEGORY + SIZE CAT
  445.                JZ      NEXT_FILE2
  446.                SUB     CUSTOM_ADDR,SIZE CAT
  447.                JMP     NEXT_FILE
  448.  
  449. CK_DOWN:       CMP     AL,DOWN_SCAN
  450.                JNZ     NEXT_FILE2
  451.                ADD     BX,SIZE CAT
  452.                CMP     BX,OFFSET CAT_END
  453.                JAE     NEXT_FILE2
  454.                MOV     CUSTOM_ADDR,BX
  455.                JMP     NEXT_FILE
  456.  
  457. DO_MENU2:      CMP     [BX.CAT_STATUS],INACTIVE
  458.                JZ      NEXT_FILE2
  459.                MOV     STATE,CUSTOM_TYPE
  460.                PUSH    BX
  461.                CALL    DISP_FILE
  462.                POP     BX
  463.                CALL    [BX.CAT_MENU]
  464.                JMP     DO_FILE
  465.  
  466. WRONG_SIZE:    CALL    DO_WRONG
  467.                JMP     FILE_END
  468.  
  469. FILE_ERR:      CALL    BEEP
  470.  
  471. FILE_END:      CALL    SET_ZIF
  472.                RET
  473.  
  474. ;----------------------------------------------;
  475. CANT_FIND      LABEL   BYTE
  476. DB "╔═════════════════════════════════════════╗",0
  477. PATH_EDIT_LEN  EQU     $ - CANT_FIND - 5
  478. DB "║ Can't find ",0
  479. CANT_FIND2     LABEL   BYTE
  480. DB                          "  Enter new path ║",0
  481. DB "║                                         ║",0
  482. DB "║ Esc to Cancel                           ║",0
  483. DB "╚═════════════════════════════════════════╝",0
  484.  
  485. NEW_PGM:       CALL    BEEP
  486.                CALL    RESTORE_DIR
  487.                CALL    CALC_WINDOW
  488.                ADD     BP,SELECT_START
  489.                MOV     DI,BP
  490.                MOV     SI,OFFSET CANT_FIND
  491.                MOV     BH,COLOR.W
  492.                CALL    WRITE_STRING
  493.                ADD     BP,CRT_WIDTH
  494.                MOV     DI,BP
  495.                CALL    WRITE_STRING
  496.                CALL    WRITE_NAME
  497.                MOV     SI,OFFSET CANT_FIND2
  498.                CALL    WRITE_STRING
  499.  
  500.                ADD     BP,CRT_WIDTH
  501.                MOV     DI,BP
  502.                MOV     ADDR_SCREEN,DI
  503.                CALL    WRITE_STRING
  504.                ADD     BP,CRT_WIDTH
  505.                MOV     DI,BP
  506.                CALL    WRITE_STRING
  507.                ADD     BP,CRT_WIDTH
  508.                MOV     DI,BP
  509.                CALL    WRITE_STRING
  510.  
  511.                MOV     CX,PATH_EDIT_LEN - 2
  512.                MOV     SI,OFFSET PGM_DRIVE
  513.                MOV     DI,OFFSET DTA
  514.                LODSB
  515.                ADD     AL,"A"
  516.                STOSB
  517.                MOV     AL,":"
  518.                STOSB
  519. NEXT_PATH:     LODSB
  520.                OR      AL,AL
  521.                JZ      NEW_PATH2
  522.                STOSB
  523.                LOOP    NEXT_PATH
  524. NEW_PATH2:     JCXZ    NEW_PATH3
  525.                MOV     AL,SPACE
  526.                REP     STOSB
  527. NEW_PATH3:     XOR     AL,AL
  528.                STOSB
  529.  
  530.                MOV     LINE_START,OFFSET DTA
  531.                MOV     LINE_END,OFFSET DTA + PATH_EDIT_LEN
  532.                MOV     AX,ADDR_SCREEN
  533.                ADD     AX,2 * 2
  534.                MOV     SCREEN_START,AX
  535.                MOV     LEGAL_CHARS,OFFSET ALL_CHARS
  536.                CALL    EDITOR
  537.                JC      NEW_PGM_END
  538.  
  539.                MOV     SI,OFFSET DTA
  540.                MOV     DI,OFFSET PGM_DRIVE
  541.                CALL    PARSE_IT
  542.                CALL    DISP_DIR
  543.                CLC
  544.  
  545. NEW_PGM_END:   RET
  546.  
  547. ;----------------------------------------------;
  548.  
  549. SIZE_MSG       LABEL   BYTE
  550. DB "╔════════════════════════════════════════════════════════════════╗",0
  551. DB "║ ",0
  552. SIZE_MSG2      LABEL   BYTE
  553. DB               " size does not match the SIZE in the .ZIF file.    ║",0
  554. XMODEM_MSG     LABEL   BYTE
  555. DB "║                                                                ║",0
  556. DB "║ However, ",0
  557. XMODEM_MSG2    LABEL   BYTE
  558. DB                        " appears to have been downloaded via the  ║",0
  559. DB "║ XMODEM protocol which rounds a file up to a 128 byte multiple. ║",0
  560. DB "║                                                                ║",0
  561. DB "║ If you have backed-up ",0
  562. XMODEM_MSG3    LABEL   BYTE
  563. DB                                     "  it's Okay to continue.     ║",0
  564. DB "║ Continue Y/N?                                                  ║",0
  565. DB "╚════════════════════════════════════════════════════════════════╝",0
  566.  
  567.  
  568. WRONG_MSG      LABEL   BYTE
  569. DB "║ It's suggest that you download from ZiffNet the latest version ║",0
  570. DB "║ of ",0
  571. WRONG_MSG2     LABEL  BYTE
  572. DB                  "            Press any key                       ║",0
  573. DB "╚════════════════════════════════════════════════════════════════╝",0
  574.  
  575. DO_XMODEM:     CALL    BEEP
  576.                CALL    DISP_SIZE
  577.                MOV     SI,OFFSET XMODEM_MSG
  578.                CALL    WRITE_STRING
  579.                ADD     BP,CRT_WIDTH
  580.                MOV     DI,BP
  581.                CALL    WRITE_STRING
  582.                CALL    WRITE_NAME
  583.                MOV     SI,OFFSET XMODEM_MSG2
  584.                CALL    WRITE_STRING
  585.  
  586.                ADD     BP,CRT_WIDTH
  587.                MOV     DI,BP
  588.                CALL    WRITE_STRING
  589.                ADD     BP,CRT_WIDTH
  590.                MOV     DI,BP
  591.                CALL    WRITE_STRING
  592.                ADD     BP,CRT_WIDTH
  593.                MOV     DI,BP
  594.                CALL    WRITE_STRING
  595.                CALL    WRITE_NAME
  596.                MOV     SI,OFFSET XMODEM_MSG3
  597.                CALL    WRITE_STRING
  598.  
  599.                ADD     BP,CRT_WIDTH
  600.                MOV     DI,BP
  601.                CALL    WRITE_STRING
  602.                ADD     BP,CRT_WIDTH
  603.                MOV     DI,BP
  604.                CALL    WRITE_STRING
  605.  
  606.                CALL    GETKEY
  607.                CMP     AL,Y_SCAN
  608.                CLC
  609.                JZ      XMODEM_END
  610.                STC
  611. XMODEM_END:    RET
  612.  
  613. ;----------------------------------------------;
  614. DO_WRONG:      CALL    BEEP
  615.                CALL    DISP_SIZE
  616.                MOV     SI,OFFSET WRONG_MSG
  617.                CALL    WRITE_STRING
  618.                ADD     BP,CRT_WIDTH
  619.                MOV     DI,BP
  620.                CALL    WRITE_STRING
  621.                CALL    WRITE_NAME
  622.                MOV     SI,OFFSET WRONG_MSG2
  623.                CALL    WRITE_STRING
  624.                ADD     BP,CRT_WIDTH
  625.                MOV     DI,BP
  626.                CALL    WRITE_STRING
  627.                CALL    GETKEY
  628.                RET
  629.  
  630. ;----------------------------------------------;
  631.  
  632. DISP_SIZE:     CALL    CALC_WINDOW
  633.                ADD     BP,CUSTOM_START
  634.                MOV     DI,BP
  635.                MOV     SI,OFFSET SIZE_MSG
  636.                MOV     BH,COLOR.W
  637.                CALL    WRITE_STRING
  638.                ADD     BP,CRT_WIDTH
  639.                MOV     DI,BP
  640.                CALL    WRITE_STRING
  641.                CALL    WRITE_NAME
  642.                MOV     SI,OFFSET SIZE_MSG2
  643.                CALL    WRITE_STRING
  644.                ADD     BP,CRT_WIDTH
  645.                MOV     DI,BP
  646.                RET
  647.  
  648. ;----------------------------------------------;
  649. WRITE_NAME:    MOV     CX,12
  650.                MOV     SI,OFFSET ASCIIZ_NAME
  651.                CALL    WRITE_LINE
  652.                CALL    PAD_LINE
  653.                RET
  654.  
  655. ;----------------------------------------------;
  656.  
  657. CALC_WINDOW:   MOV     AX,WINDOW_TOP
  658.                CALL    CALC_ADDR
  659.                MOV     BP,DI
  660.                RET
  661. ;----------------------------------------------;
  662.  
  663. SEARCH:        PUSH    DS
  664.                CMP     AH,"a"
  665.                JB      DO_SEARCH
  666.                CMP     AH,"z"
  667.                JA      DO_SEARCH
  668.                AND     AH,5FH
  669.  
  670. DO_SEARCH:     MOV     SI,BAR_ADDR
  671.                MOV     DS,FILENAME_SEG
  672.                CMP     [SI],AH
  673.                JZ      NEXT_SEARCH
  674.                XOR     SI,SI
  675.                JMP     SHORT NEXT_SEARCH2
  676.  
  677. NEXT_SEARCH:   ADD     SI,SIZE FILE_RECORD
  678. NEXT_SEARCH2:  CMP     BYTE PTR[SI],-1
  679.                JZ      NO_MATCH
  680.                CMP     [SI],AH
  681.                JNZ     NEXT_SEARCH
  682.  
  683.                POP     DS
  684.                MOV     BAR_ADDR,SI
  685.                MOV     AX,LISTING_LEN
  686.                SHR     AX,1
  687.                MOV     BX,SIZE FILE_RECORD
  688.                MUL     BX
  689.                SUB     SI,AX
  690.                JNC     STORE_MATCH
  691.                XOR     SI,SI
  692. STORE_MATCH:   MOV     LISTING_ADDR,SI
  693.                MOV     FILE_CURRENT,FALSE
  694.                JMP     SHORT SEARCH_END
  695.  
  696. NO_MATCH:      POP     DS
  697.                CALL    BEEP
  698.  
  699. SEARCH_END:    CALL    DISP_LISTING
  700.                CALL    DISP_FILE
  701.                RET
  702.  
  703. ;----------------------------------------------;
  704.  
  705. L_DISPATCH     DB      UP_SCAN,      DOWN_SCAN,   PGUP_SCAN,    PGDN_SCAN
  706.                DB      HOME_SCAN,    END_SCAN
  707.  
  708. L_LEN          EQU     $ - L_DISPATCH
  709.  
  710.                DW      LUP,          LDOWN,       LPGUP,        LPGDN
  711.                DW      LHOME,        LEND
  712.  
  713.  
  714. ;----------------------------------------------;
  715. ; INPUT: AX=Listing page; BP=BAR_ADDR; DX=LISTING_ADDR; CX=LAST_ADDR.
  716. ; OUTPUT: LISTING_FLAG=TRUE if listing changed.
  717.  
  718. LUP:           SUB     BP,SIZE FILE_RECORD     ;Move bar up a line.
  719.                JL      LPAGE_END               ;If < 0, ignore.
  720.                CMP     BP,DX                   ;If bar below top, OK.
  721.                JAE     LPAGE_UPDATE
  722.                SUB     DX,SIZE FILE_RECORD     ;Else, move listing up a line.
  723.                JMP     SHORT LPAGE_UPDATE
  724.  
  725. LDOWN:         ADD     BP,SIZE FILE_RECORD     ;Move bar down a line.
  726.                CMP     BP,CX                   ;If > last line, then ignore.
  727.                JA      LPAGE_END
  728.                ADD     AX,DX                   ;Listing top + page length =
  729.                CMP     BP,AX                   ; listing bottom; If bar below
  730.                JB      LPAGE_UPDATE            ; listing bottom, OK.
  731.                ADD     DX,SIZE FILE_RECORD     ;Else move listing down a line.
  732.                JMP     SHORT LPAGE_UPDATE
  733.  
  734. LPGUP:         SUB     BP,AX                   ;Move bar up a page.
  735.                SUB     DX,AX                   ;Move listing up a page.
  736.                JC      LHOME                   ;If listing < top, then home.
  737.                JMP     SHORT LPAGE_UPDATE      ;Else, OK.
  738.  
  739. LPGDN:         ADD     DX,AX                   ;Move listing down a page.
  740.                CMP     DX,CX                   ;If <= last line, do bar.
  741.                JBE     DO_BAR
  742.                SUB     DX,AX                   ;Else, back to where we were
  743.                MOV     BP,CX                   ; and move bar to last line
  744.                JMP     SHORT LPAGE_UPDATE      ; and update.
  745. DO_BAR:        ADD     BP,AX                   ;Move bar down a page.
  746.                CMP     BP,CX                   ;If bar <= last line, OK.
  747.                JBE     LPAGE_UPDATE
  748.                MOV     BP,CX                   ;Else, move bar to last line.
  749.                JMP     SHORT LPAGE_UPDATE
  750.  
  751. LHOME:         XOR     BP,BP                   ;Move bar to top.
  752.                XOR     DX,DX                   ;Move listing to top.
  753.                JMP     SHORT LPAGE_UPDATE
  754.  
  755. LEND:          MOV     BP,CX                   ;Move bar to last line.
  756.                ADD     CX,SIZE FILE_RECORD     ;Last line + 1 - page length =
  757.                SUB     CX,AX                   ; top of last page.
  758.                CMP     DX,CX                   ;If less than a full page,
  759.                JG      LPAGE_UPDATE            ; then already at last page.
  760.                MOV     DX,CX                   ;Else, move listing to last page.
  761.  
  762. LPAGE_UPDATE:  MOV     BAR_ADDR,BP             ;Store the new bar
  763.                MOV     LISTING_ADDR,DX         ; and listing line start.
  764.                MOV     FILE_CURRENT,FALSE
  765.                MOV     FAIL_FLAG,FALSE
  766.  
  767. LPAGE_END:     RET
  768.  
  769. ;----------------------------------------------;
  770.  
  771. FIND_FILES:    CALL    SET_ZIF
  772.                XOR     BP,BP                   ;ES:BP -> filename storage.
  773.  
  774.                MOV     DX,OFFSET STAR_DOT_ZIF
  775.                XOR     CX,CX
  776.                MOV     AH,4EH                  ;Find first.
  777.                INT     21H
  778.                JC      FILES_DONE              ;If no, assumed right.
  779.  
  780.                PUSH    ES
  781.                MOV     ES,FILENAME_SEG
  782.                XOR     DI,DI
  783.                MOV     AX,SPACE SHL 8 + SPACE
  784.                MOV     CX,FILENAME_SIZE / 2 * KILOBYTES
  785.                REP     STOSW                   ;Initialize with spaces.
  786.                POP     ES
  787.  
  788. FIND_NEXT:     MOV     DX,OFFSET DTA.FILE_NAME
  789.                CALL    READ_ZIF
  790.                JC      FILES_DONE
  791.                CALL    STORE_NAME              ;Store a filename.
  792.                CMP     BP,TEMP_RECORD - SIZE FILE_RECORD
  793.                JA      FILES_DONE
  794.                MOV     AH,4FH                  ;Find Next Matching.
  795.                INT     21H
  796.                JNC     FIND_NEXT               ;If successful store filename.
  797.  
  798. FILES_DONE:    PUSH    ES
  799.                MOV     ES,FILENAME_SEG
  800.                MOV     AX,-1                   ;Else, mark the end with -1.
  801.                MOV     DI,BP
  802.                STOSW
  803.                POP     ES
  804.                SUB     DI,SIZE FILE_RECORD + 2
  805.                JNC     STORE_LAST
  806.                XOR     DI,DI
  807. STORE_LAST:    MOV     LAST_ADDR,DI
  808.                CALL    SORT                    ;Sort 'em.
  809.  
  810. FILES_END:     RET
  811.  
  812. ;----------------------------------------------;
  813. ; INPUT: DX-> filename
  814. ; OUTPUT: CF = 1 if failed.
  815.  
  816. READ_ZIF:      MOV     AX,3D00H
  817.                INT     21H
  818.                JC      OPEN_END
  819.                CMP     FAIL_FLAG,TRUE
  820.                STC
  821.                JZ      OPEN_FAIL
  822.  
  823.                MOV     BX,AX
  824.                CALL    READZ
  825.                JNC     OPEN_END
  826.  
  827. OPEN_FAIL:     CALL    BEEP
  828.                MOV     FAIL_FLAG,FALSE
  829.                STC
  830.  
  831. OPEN_END:      RET
  832.  
  833. ;----------------------------------------------;
  834. ; INPUT:  BX = filehandle.
  835. ; OUTPUT: CF=1 if read failed.
  836.  
  837. READZ:         PUSH    DS
  838.                MOV     DS,ZIF_BUFF_SEG
  839.                XOR     DX,DX
  840.                MOV     CX,ZIF_BUFF_SIZE * KILOBYTES - 1
  841.                MOV     AH,3FH
  842.                INT     21H
  843.  
  844.                MOV     CS:ZIF_BYTES,AX
  845.                MOV     SI,AX
  846.                MOV     BYTE PTR [SI],CTRL_Z
  847.                JC      CLOSE
  848.                CMP     CS:FAIL_FLAG,TRUE
  849.                STC
  850.                JZ      CLOSE
  851.  
  852. CAPITALIZE:    XOR     SI,SI
  853.                MOV     CX,AX
  854.                JCXZ    CLOSE1
  855.                XOR     AH,AH                   ;Quotes flag.
  856. NEXT_CAP:      LODSB
  857.                CMP     AL,CTRL_Z
  858.                JZ      CAP_END
  859.                CMP     AL,AH
  860.                JZ      CLOSE_QUOTES
  861.                CMP     AH,DOUBLE_QUOTES
  862.                JZ      NEXT_CAP
  863.  
  864.                CMP     AL,DOUBLE_QUOTES
  865.                JZ      OPEN_QUOTES
  866.                CMP     AL,"a"
  867.                JB      NEXT_CAP
  868.                CMP     AL,"z"
  869.                JA      NEXT_CAP
  870.                AND     BYTE PTR [SI - 1],5FH
  871.                JMP     NEXT_CAP
  872.  
  873. OPEN_QUOTES:   MOV     AH,AL
  874.                JMP     NEXT_CAP
  875.  
  876. CLOSE_QUOTES:  XOR     AH,AH
  877.                JMP     NEXT_CAP
  878. CAP_END:
  879.  
  880. CLOSE1:        CLC
  881.  
  882. CLOSE:         PUSHF
  883.                MOV     AH,3EH
  884.                INT     21H
  885.                POPF
  886.  
  887. READ_END:      POP     DS
  888.                MOV     FAIL_FLAG,FALSE
  889.                RET
  890.  
  891. ;----------------------------------------------;
  892. ; INPUT: DX-> filename
  893. ; OUTPUT: CF = 1 if failed.
  894.  
  895. READ_PGM:      MOV     AX,3D00H
  896.                INT     21H
  897.                JC      OPEN_END2
  898.                CMP     FAIL_FLAG,TRUE
  899.                STC
  900.                JZ      OPEN_FAIL2
  901.  
  902.                MOV     BX,AX
  903.                CALL    READP
  904.                JNC     OPEN_END
  905.  
  906. OPEN_FAIL2:    CALL    BEEP
  907.                MOV     FAIL_FLAG,FALSE
  908.                STC
  909.  
  910. OPEN_END2:     RET
  911.  
  912. ;----------------------------------------------;
  913. ; INPUT:  BX = filehandle.
  914. ; OUTPUT: CF=1 if read failed.
  915.  
  916. READP:         PUSH    DS
  917.                MOV     DS,PGM_BUFF_SEG
  918.                XOR     DX,DX
  919.                MOV     CX,PGM_BUFF_SIZE * KILOBYTES - 1
  920.                MOV     AH,3FH
  921.                INT     21H
  922.                JC      CLOSE2
  923.                CMP     CS:FAIL_FLAG,TRUE
  924.                STC
  925.                JZ      CLOSE2
  926.                MOV     CS:PGM_BYTES,AX
  927.  
  928.                CLC
  929.  
  930. CLOSE2:        PUSHF
  931.                MOV     AH,3EH
  932.                INT     21H
  933.                POPF
  934.  
  935. READP_END:     POP     DS
  936.                MOV     FAIL_FLAG,FALSE
  937.                RET
  938.  
  939. ;----------------------------------------------;
  940. ;INPUT:         BP->filename storage.
  941. ;OUTPUT:        BP->next storage.
  942.  
  943. FILE_STR       DB      "[FILE]"
  944. FILE_STR_LEN   EQU     $ - FILE_STR
  945. FILENAME_STR   DB      "FILENAME"
  946. FILENAME_STR_LEN       EQU $ - FILENAME_STR
  947.  
  948. STORE_NAME:    PUSH    DS
  949.                MOV     DS,ZIF_BUFF_SEG
  950.                XOR     BX,BX
  951.  
  952. NEXT_FILE_STR: MOV     DI,OFFSET FILE_STR
  953.                MOV     SI,BX
  954.                CMP     BYTE PTR [SI],CTRL_Z
  955.                JZ      NAME_END1
  956.                INC     BX
  957.                MOV     CX,FILE_STR_LEN
  958.                REPZ    CMPSB
  959.                JNZ     NEXT_FILE_STR
  960.                ADD     BX,FILE_STR_LEN - 1
  961.                MOV     SI,BX
  962.                CALL    PARSE_LINES
  963.                MOV     BX,SI
  964.  
  965. NEXT_FILE_STR2:MOV     DI,OFFSET FILENAME_STR
  966.                MOV     SI,BX
  967.                CMP     BYTE PTR [SI],CTRL_Z
  968.                JZ      NAME_END1
  969.                CMP     BYTE PTR [SI],"["
  970.                JZ      NAME_END1
  971.                INC     BX
  972.                MOV     CX,FILENAME_STR_LEN
  973.                REPZ    CMPSB
  974.                JNZ     NEXT_FILE_STR2
  975.  
  976.  
  977.                CALL    PARSE_LINE              ;SI-> name start.
  978.                JC      NAME_END1
  979.                PUSH    ES                      ;Preserve extra segment.
  980.                MOV     ES,CS:FILENAME_SEG
  981.                MOV     DI,BP
  982.                MOV     CX,SIZE LIST_NAME       ;Store 12 bytes of filename.
  983.                JMP     SHORT NEXT_STORE
  984.  
  985. EXTENSION:     ADD     DI,CX
  986.                MOV     CX,3
  987.                SUB     DI,CX
  988.  
  989. NEXT_STORE:    LODSB                           ;Get a byte.
  990.                CMP     AL,SPACE
  991.                JBE     END_STORE               ;If yes, finish with blanks.
  992.                CMP     AL,"."                  ;Is it the period?
  993.                JZ      EXTENSION
  994.                STOSB                           ;Store byte.
  995.                LOOP    NEXT_STORE              ;Get next byte.
  996. END_STORE:     ADD     BP,SIZE LIST_NAME
  997.                INC     CS:FILE_CNT
  998.                POP     ES
  999.  
  1000. NAME_END1:     POP     DS
  1001.  
  1002. NAME_END:      RET                             ;Done here.
  1003.  
  1004. ;----------------------------------------------;
  1005.  
  1006. DISP_FILE:     CMP     FILE_CURRENT,TRUE
  1007.                JZ      DISP_FILE2
  1008.                CALL    MAKE_ZIF_NAME
  1009.                MOV     DX,OFFSET ASCIIZ_NAME
  1010.                CALL    READ_ZIF
  1011.                JC      NO_FILE
  1012.                MOV     FILE_CURRENT,TRUE
  1013.                CALL    PARSE_FILE
  1014.  
  1015. DISP_FILE2:    CALL    DISP_CUSTOM
  1016.                JMP     SHORT DISP_FILE_END
  1017.  
  1018. NO_FILE:       CALL    CLEAR_FILE
  1019.                CALL    BEEP
  1020.  
  1021. DISP_FILE_END: RET
  1022.  
  1023. ;----------------------------------------------;
  1024. ACTIVE         EQU     0
  1025. INACTIVE       EQU     -1
  1026.  
  1027. CAT            STRUC
  1028. CAT_STATUS     DB      INACTIVE
  1029. CAT_LEN        DB      ?
  1030. CAT_TEXT       DB      "           "
  1031. CAT_NUL        DB      0
  1032. CAT_MENU       DW      ?
  1033. CAT_PARSE      DW      ?
  1034. CAT            ENDS
  1035.  
  1036. CATEGORY       CAT     <,5, "FILE]",,      DUMMY_RET,    FILE_PARSE>
  1037.                CAT     <,6, "COLOR]",,     COLOR_MENU,   COLOR_PARSE>
  1038.                CAT     <,7, "HOTKEY]",,    HOTKEY_MENU,  HOTKEY_PARSE>
  1039.                CAT     <,6, "MODEM]",,     MODEM_MENU,   MODEM_PARSE>
  1040.                CAT     <,8, "PRINTER]",,   PRINTER_MENU, PRINTER_PARSE>
  1041.                CAT     <,5, "TEXT]",,      TEXT_MENU,    TEXT_PARSE>
  1042.                CAT     <,7, "NUMBER]",,    NUMBER_MENU,  NUMBER_PARSE>
  1043.                CAT     <,10,"PICK LIST]",, PICK_MENU,    PICK_PARSE>
  1044.  
  1045. CAT_END        EQU     $
  1046. CATEGORY_LEN   EQU     (CAT_END - CATEGORY ) / SIZE CAT
  1047.  
  1048. CUSTOM_ADDR    DW      ?                       ;Index into custom menu.
  1049.  
  1050. VARS           LABEL   BYTE
  1051.  
  1052. FILE_SIZE      DW      ?,?
  1053. COLOR_MAX      EQU     7
  1054. COLOR_MENUS    DW      COLOR_MAX DUP (?)
  1055.  
  1056. TEXT_MAX       EQU     7
  1057. TEXT_MENUS     DW      TEXT_MAX DUP (?)
  1058.  
  1059. NUM_MAX        EQU     7
  1060. NUMBER_MENUS   DW      NUM_MAX DUP (?)
  1061.  
  1062. PICK_MAX       EQU     6
  1063. PICK_MENUS     DW      PICK_MAX DUP (?)
  1064. ENTRY_MENUS    DW      PICK_MAX DUP (PICK_MAX DUP (?))
  1065.  
  1066. SHIFT_ADDR     DW      ?
  1067. SHIFT_TEXT_ADDR DW     ?
  1068. SCAN_ADDR      DW      ?
  1069. SCAN_TEXT_ADDR DW      ?
  1070.  
  1071. VARS_LEN       EQU     $ - VARS
  1072.  
  1073. COLOR_ADDRS    DW      COLOR_MAX DUP (?)
  1074. COLOR_VALUES   DW      COLOR_MAX DUP (?)
  1075.  
  1076. TEXT_ADDRS     DW      TEXT_MAX DUP (?)
  1077. TEXT_LENGTH    DW      TEXT_MAX DUP (?)
  1078. STRING_MAX     EQU     27
  1079. TEXT_EDIT      DB      TEXT_MAX DUP (STRING_MAX DUP (?))
  1080.  
  1081. NUMBER_ADDRS   DW      NUM_MAX DUP (?)
  1082. NUMBER_TYPE    DW      NUM_MAX DUP (?)
  1083. RANGE_LOW      DW      NUM_MAX DUP (?)
  1084. RANGE_HIGH     DW      NUM_MAX DUP (?)
  1085. INTEGER_MAX    EQU     7
  1086. NUMBER_EDIT    DB      NUM_MAX DUP (INTEGER_MAX DUP (?))
  1087. NUMBER_RANGE   DB      INTEGER_MAX + 1 DUP (?)
  1088.  
  1089. PICK_ADDRS     DW      PICK_MAX DUP (?)
  1090. PICK_TYPES     DW      PICK_MAX DUP (?)
  1091. ENTRY_VALUES   DW      PICK_MAX DUP (PICK_MAX DUP (?))
  1092.  
  1093. ;--------------;
  1094.  
  1095. INIT_VARS:     MOV     CUSTOM_ADDR,OFFSET CATEGORY + SIZE CAT
  1096.  
  1097.                MOV     BP,CATEGORY_LEN
  1098.                MOV     SI,OFFSET CATEGORY
  1099.                MOV     AX,INACTIVE
  1100. NEXT_INACTIVE: MOV     [SI],AL
  1101.                ADD     SI,SIZE CAT
  1102.                DEC     BP
  1103.                JNZ     NEXT_INACTIVE
  1104.  
  1105.                MOV     CX,VARS_LEN
  1106.                MOV     DI,OFFSET VARS
  1107.                REP     STOSB
  1108.                RET
  1109.  
  1110. ;----------------------------------------------;
  1111.  
  1112. PARSE_FILE:    PUSH    DS
  1113.                CALL    INIT_VARS
  1114.                MOV     DS,ZIF_BUFF_SEG
  1115.                XOR     SI,SI
  1116. NEXT_BRACKET:  LODSB
  1117.                CMP     AL,CTRL_Z
  1118.                JZ      PARSE_FILE_END
  1119.                CMP     AL,"["
  1120.                JNZ     NEXT_BRACKET
  1121.  
  1122.                CMP     BYTE PTR [SI],CTRL_Z
  1123.                JZ      PARSE_FILE_END
  1124.                MOV     BP,CATEGORY_LEN
  1125.                MOV     DX,SI
  1126.                MOV     BX,OFFSET CATEGORY
  1127. NEXT_CAT:      MOV     SI,DX
  1128.                MOV     DI,BX
  1129.                ADD     DI,CAT_TEXT
  1130.                MOV     CL,CS:[BX.CAT_LEN]
  1131.                XOR     CH,CH
  1132.                REP     CMPSB
  1133.                JZ      FOUND_CAT
  1134.                ADD     BX,SIZE CAT
  1135.                DEC     BP
  1136.                JNZ     NEXT_CAT
  1137.                INC     DX
  1138.                MOV     SI,DX
  1139.                JMP     NEXT_BRACKET
  1140.  
  1141. FOUND_CAT:     CALL    PARSE_LINES
  1142.                JC      NEXT_BRACKET
  1143.                PUSH    BX
  1144.                CALL    CS:[BX.CAT_PARSE]
  1145.                POP     BX
  1146.                JC      NEXT_BRACKET
  1147.                MOV     CS:[BX.CAT_STATUS],ACTIVE
  1148.                JMP     NEXT_BRACKET
  1149.  
  1150. PARSE_FILE_END:POP     DS
  1151.                RET
  1152.  
  1153. ;----------------------------------------------;
  1154. ;INPUT: DS:SI->ZIF_BUFF_SEG:OFFSET; BX->CATEGORY:OFFSET
  1155. ;OUTPUT: DS:SI->end of category; CF=1 if no valid parameters found.
  1156.  
  1157. SIZE_STR       DB      "SIZE"
  1158. SIZE_STR_LEN   EQU     $ - SIZE_STR
  1159.  
  1160. ;--------------;
  1161. FILE_PARSE:    MOV     BP,SIZE_STR_LEN
  1162.                MOV     BX,OFFSET SIZE_STR
  1163.                CALL    PARSE_KEY
  1164.                JC      FILE_PARSE_END
  1165.                CALL    GET_NUMBER
  1166.                JC      FILE_PARSE_END
  1167.                MOV     CS:FILE_SIZE[0],AX
  1168.                MOV     CS:FILE_SIZE[2],CX
  1169. FILE_PARSE_END:RET
  1170.  
  1171. ;--------------;
  1172. ENTRY_INDEX    DW      ?
  1173. PICK_ADDR      DW      ?
  1174.  
  1175. PICK_PARSE:    XOR     BX,BX
  1176.                MOV     CS:ENTRY_INDEX,0
  1177. NEXT_PICK:     MOV     BP,SI
  1178.                INC     BP
  1179.                CALL    PARSE_STRING
  1180.                JC      PICK_END
  1181.                CALL    PARSE_LINE
  1182.                JC      PICK_END
  1183.                CALL    GET_NUMBER
  1184.                JC      PICK_END
  1185.                SUB     AX,100H
  1186.                JC      PICK_END
  1187.                MOV     CS:PICK_ADDR,AX
  1188.                CALL    PARSE_LINE
  1189.                JC      PICK_END
  1190.  
  1191.                PUSH    BX
  1192.                PUSH    BP
  1193.                MOV     BP,SIZE_STR_LEN
  1194.                MOV     BX,OFFSET SIZE_STR
  1195.                CALL    PARSE_KEY
  1196.                POP     BP
  1197.                POP     BX
  1198.                JC      PICK_END
  1199.                CALL    PARSE_LINE
  1200.                JC      PICK_END
  1201.  
  1202.                LODSB
  1203.                CMP     AL,"B"
  1204.                JZ      STORE_PICK
  1205.                CMP     AL,"W"
  1206.                STC
  1207.                JNZ     PICK_END
  1208.  
  1209. STORE_PICK:    MOV     CS:PICK_TYPES[BX],AX
  1210.                CALL    PARSE_END2
  1211.                CALL    PARSE_LINES
  1212.                JC      PICK_END
  1213.                CALL    PARSE_ENTRY
  1214.                JC      PICK_END
  1215.                MOV     AX,CS:PICK_ADDR
  1216.                MOV     CS:PICK_ADDRS[BX],AX
  1217.                MOV     CS:PICK_MENUS[BX],BP
  1218.                ADD     CS:ENTRY_INDEX,PICK_MAX * 2
  1219.                INC     BX
  1220.                INC     BX
  1221.                CMP     BX,PICK_MAX * 2
  1222.                JAE     PICK_END
  1223.                CALL    PARSE_LINES
  1224.                JNC     NEXT_PICK
  1225.  
  1226.                CLC
  1227.  
  1228. PICK_END:      RET
  1229.  
  1230. ;--------------;
  1231. ENTRY_STR      DB      "ENTRY"
  1232. ENTRY_STR_LEN  EQU     $ - ENTRY_STR
  1233.  
  1234. VALUE_STR      DB      "VALUE"
  1235. VALUE_STR_LEN  EQU     $ - VALUE_STR
  1236.  
  1237. ENTRY_ADDR     DW      ?
  1238. ENTRY_MAX      DW      ?
  1239.  
  1240. PARSE_ENTRY:   PUSH    BX
  1241.                PUSH    BP
  1242.                MOV     BX,CS:ENTRY_INDEX
  1243.                MOV     AX,BX
  1244.                ADD     AX,PICK_MAX * 2
  1245.                MOV     CS:ENTRY_MAX,AX
  1246.  
  1247. NEXT_ENTRY:    PUSH    BX
  1248.                MOV     BP,ENTRY_STR_LEN
  1249.                MOV     BX,OFFSET ENTRY_STR
  1250.                CALL    PARSE_KEY
  1251.                POP     BX
  1252.                JC      PARSE_E_END
  1253.                CALL    PARSE_LINE
  1254.                JC      PARSE_E_END
  1255.                MOV     BP,SI
  1256.                INC     BP
  1257.                CALL    PARSE_STRING
  1258.                JC      PARSE_E_END
  1259.                CALL    PARSE_LINE
  1260.                JC      PARSE_E_END
  1261.  
  1262.                PUSH    BX
  1263.                PUSH    BP
  1264.                MOV     BP,VALUE_STR_LEN
  1265.                MOV     BX,OFFSET VALUE_STR
  1266.                CALL    PARSE_KEY
  1267.                POP     BP
  1268.                POP     BX
  1269.                JC      PARSE_E_END
  1270.                CALL    PARSE_LINE
  1271.                JC      PARSE_E_END
  1272.                CALL    GET_NUMBER
  1273.                JC      PARSE_E_END
  1274.                MOV     CS:ENTRY_VALUES[BX],AX
  1275.                MOV     CS:ENTRY_MENUS[BX],BP
  1276.                INC     BX
  1277.                INC     BX
  1278.                CMP     BX,CS:ENTRY_MAX
  1279.                JAE     PARSE_E_END
  1280.                CALL    PARSE_LINES
  1281.                JC      PARSE_E_DONE
  1282.                CMP     AL,DOUBLE_QUOTES
  1283.                JNZ     NEXT_ENTRY
  1284. PARSE_E_DONE:  CLC
  1285.  
  1286. PARSE_E_END:   POP     BP
  1287.                POP     BX
  1288.                RET
  1289.  
  1290. ;--------------;
  1291. COLOR_PARSE:   XOR     BX,BX                   ;Index.
  1292. NEXT_COLOR:    MOV     BP,SI                   ;Save string start.
  1293.                INC     BP                      ;Bump past quotes.
  1294.                CALL    PARSE_STRING
  1295.                JC      COLOR_END
  1296.                CALL    PARSE_LINE
  1297.                JC      COLOR_END
  1298.                CALL    GET_NUMBER
  1299.                JC      COLOR_END
  1300.                SUB     AX,100H
  1301.                JC      COLOR_END
  1302.                MOV     CS:COLOR_MENUS[BX],BP   ;String start.
  1303.                MOV     CS:COLOR_ADDRS[BX],AX   ;Prog address.
  1304.                INC     BX
  1305.                INC     BX
  1306.                CMP     BX,COLOR_MAX * 2
  1307.                JAE     COLOR_END
  1308.                CALL    PARSE_LINES
  1309.                JNC     NEXT_COLOR
  1310.  
  1311.                CLC
  1312.  
  1313. COLOR_END:     RET
  1314.  
  1315. ;--------------;
  1316. SHIFT_STR      DB      "SHIFT"
  1317. SHIFT_LEN      EQU     $ - SHIFT_STR
  1318. TEXT_STR       DB      "TEXT"
  1319. TEXT_LEN       EQU     $ - TEXT_STR
  1320. SCAN_STR       DB      "SCAN"
  1321. SCAN_LEN       EQU     $ - SCAN_STR
  1322.  
  1323. GOOD_PARA      DB      FALSE  ;TRUE if valid parameters
  1324.  
  1325. HOTKEY_PARSE:  MOV     CS:GOOD_PARA,FALSE
  1326.                PUSH    SI
  1327. NEXT_SHIFT:    MOV     BP,SHIFT_LEN
  1328.                MOV     BX,OFFSET SHIFT_STR
  1329.                CALL    PARSE_KEY
  1330.                JNC     GOT_SHIFT
  1331.                CALL    PARSE_LINES
  1332.                JNC     NEXT_SHIFT
  1333.                JMP     SHORT CK_SCAN
  1334.  
  1335. GOT_SHIFT:     CALL    PARSE_LINE
  1336.                JC      CK_SCAN
  1337.                CALL    GET_NUMBER
  1338.                JC      CK_SCAN
  1339.                SUB     AX,100H
  1340.                JC      CK_SCAN
  1341.                MOV     CS:SHIFT_ADDR,AX
  1342.                MOV     CS:GOOD_PARA,TRUE
  1343.                CALL    PARSE_LINE
  1344.                JC      CK_SCAN
  1345.  
  1346.                MOV     BP,TEXT_LEN
  1347.                MOV     BX,OFFSET TEXT_STR
  1348.                CALL    PARSE_KEY
  1349.                JC      CK_SCAN
  1350.                CALL    PARSE_LINE
  1351.                JC      CK_SCAN
  1352.                CALL    GET_NUMBER
  1353.                JC      CK_SCAN
  1354.                SUB     AX,100H
  1355.                JC      CK_SCAN
  1356.                MOV     CS:SHIFT_TEXT_ADDR,AX
  1357.  
  1358. CK_SCAN:       POP     SI
  1359. NEXT_SCAN:     MOV     BP,SCAN_LEN
  1360.                MOV     BX,OFFSET SCAN_STR
  1361.                CALL    PARSE_KEY
  1362.                JNC     GOT_SCAN
  1363.                CALL    PARSE_LINES
  1364.                JNC     NEXT_SCAN
  1365.                JMP     SHORT HOT_END1
  1366.  
  1367. GOT_SCAN:      CALL    PARSE_LINE
  1368.                JC      HOT_END1
  1369.                CALL    GET_NUMBER
  1370.                JC      HOT_END1
  1371.                SUB     AX,100H
  1372.                JC      HOT_END1
  1373.                MOV     CS:SCAN_ADDR,AX
  1374.                CALL    PARSE_LINE
  1375.                JC      HOT_END1
  1376.  
  1377.                MOV     BP,TEXT_LEN
  1378.                MOV     BX,OFFSET TEXT_STR
  1379.                CALL    PARSE_KEY
  1380.                JC      HOT_END1
  1381.                CALL    PARSE_LINE
  1382.                JC      HOT_END1
  1383.                CALL    GET_NUMBER
  1384.                JC      HOT_END1
  1385.                SUB     AX,100H
  1386.                JC      HOT_END1
  1387.                MOV     CS:SCAN_TEXT_ADDR,AX
  1388.  
  1389. HOT_END1:      CMP     CS:GOOD_PARA,TRUE
  1390.                CLC
  1391.                JZ      HOT_END
  1392.                STC
  1393.  
  1394. HOT_END:       RET
  1395.  
  1396. ;--------------;
  1397. COM_STR        DB      "COM"
  1398. COM_LEN        EQU     $ - COM_STR
  1399. COM_ADDR       DW      ?
  1400.  
  1401. MODEM_PARSE:   MOV     BP,COM_LEN
  1402.                MOV     BX,OFFSET COM_STR
  1403.                CALL    PARSE_KEY
  1404.                JC      MODEM_END
  1405.                CALL    PARSE_LINE
  1406.                JC      MODEM_END
  1407.                CALL    GET_NUMBER
  1408.                JC      MODEM_END
  1409.                SUB     AX,100H
  1410.                JC      MODEM_END
  1411.                MOV     CS:COM_ADDR,AX
  1412. MODEM_END:     RET
  1413.  
  1414. ;--------------;
  1415. LPT_STR        DB      "LPT"
  1416. LPT_LEN        EQU     $ - LPT_STR
  1417. LPT_ADDR       DW      ?
  1418.  
  1419. PRINTER_PARSE: MOV     BP,LPT_LEN
  1420.                MOV     BX,OFFSET LPT_STR
  1421.                CALL    PARSE_KEY
  1422.                JC      LPT_END
  1423.                CALL    PARSE_LINE
  1424.                JC      LPT_END
  1425.                CALL    GET_NUMBER
  1426.                JC      LPT_END
  1427.                SUB     AX,100H
  1428.                JC      LPT_END
  1429.                MOV     CS:LPT_ADDR,AX
  1430. LPT_END:       RET
  1431.  
  1432.                RET
  1433.  
  1434. ;--------------;
  1435. LENGTH_STR     DB      "LENGTH"
  1436. LENGTH_STR_LEN EQU     $ - LENGTH_STR
  1437.  
  1438.  
  1439. TEXT_PARSE:    XOR     BX,BX                   ;Index.
  1440. NEXT_TEXT:     MOV     BP,SI                   ;Save string start.
  1441.                INC     BP                      ;Bump past quotes.
  1442.                CALL    PARSE_STRING
  1443.                JC      TEXT_END
  1444.                CALL    PARSE_LINE
  1445.                JC      TEXT_END
  1446.                CALL    GET_NUMBER
  1447.                JC      TEXT_END
  1448.                SUB     AX,100H
  1449.                JC      TEXT_END
  1450.                MOV     CS:TEXT_ADDRS[BX],AX   ;Prog address.
  1451.                CALL    PARSE_LINE
  1452.                JC      TEXT_END
  1453.  
  1454.                PUSH    BX
  1455.                PUSH    BP
  1456.                MOV     BP,LENGTH_STR_LEN
  1457.                MOV     BX,OFFSET LENGTH_STR
  1458.                CALL    PARSE_KEY
  1459.                POP     BP
  1460.                POP     BX
  1461.                JC      TEXT_END
  1462.                CALL    PARSE_LINE
  1463.                JC      TEXT_END
  1464.                CALL    GET_NUMBER
  1465.                JC      TEXT_END
  1466.                MOV     CS:TEXT_LENGTH[BX],AX
  1467.                MOV     CS:TEXT_MENUS[BX],BP   ;String start.
  1468.                INC     BX
  1469.                INC     BX
  1470.                CMP     BX,TEXT_MAX * 2
  1471.                JAE     TEXT_END
  1472.                CALL    PARSE_LINES
  1473.                JNC     NEXT_TEXT
  1474.  
  1475.                CLC
  1476.  
  1477. TEXT_END:      RET
  1478.  
  1479. ;--------------;
  1480. RANGE_STR      DB      "RANGE"
  1481. RANGE_STR_LEN  EQU     $ - RANGE_STR
  1482.  
  1483. NUMBER_PARSE:  XOR     BX,BX                   ;Index.
  1484. NEXT_NUM:      MOV     BP,SI                   ;Save string start.
  1485.                INC     BP                      ;Bump past quotes.
  1486.                CALL    PARSE_STRING
  1487.                JC      LILLY_N_END
  1488.                CALL    PARSE_LINE
  1489.                JC      LILLY_N_END
  1490.                CALL    GET_NUMBER
  1491.                JC      LILLY_N_END
  1492.                SUB     AX,100H
  1493.                JC      LILLY_N_END
  1494.                MOV     CS:NUMBER_ADDRS[BX],AX
  1495.                CALL    PARSE_LINE
  1496.                JC      LILLY_N_END
  1497.  
  1498.                PUSH    BX
  1499.                PUSH    BP
  1500.                MOV     BP,SIZE_STR_LEN
  1501.                MOV     BX,OFFSET SIZE_STR
  1502.                CALL    PARSE_KEY
  1503.                POP     BP
  1504.                POP     BX
  1505.                JC      LILLY_N_END
  1506.                CALL    PARSE_LINE
  1507.                JC      LILLY_N_END
  1508.                LODSB
  1509.                CMP     AL,"B"
  1510.                JZ      STORE_NUMBER
  1511.                CMP     AL,"W"
  1512.                JZ      STORE_NUMBER
  1513. LILLY_N_END:   STC
  1514.                JMP     SHORT N_END
  1515.  
  1516. STORE_NUMBER:  MOV     CS:NUMBER_TYPE[BX],AX
  1517.                MOV     CS:NUMBER_MENUS[BX],BP   ;String start.
  1518.                MOV     CS:RANGE_LOW[BX],0
  1519.                MOV     CX,-1
  1520.                CMP     AL,"W"
  1521.                JZ      STORE_RANGE
  1522.                MOV     CX,255
  1523. STORE_RANGE:   MOV     CS:RANGE_HIGH[BX],CX
  1524.  
  1525.                MOV     CX,4
  1526. NEXT_SIZE2:    LODSB
  1527.                CMP     AL,SPACE
  1528.                JBE     DO_RANGE
  1529.                LOOP    NEXT_SIZE2
  1530. DO_RANGE:      DEC     SI
  1531.                CALL    PARSE_LINE
  1532.                JC      NEXT_NUM2
  1533.                PUSH    BX
  1534.                PUSH    BP
  1535.                MOV     BP,RANGE_STR_LEN
  1536.                MOV     BX,OFFSET RANGE_STR
  1537.                CALL    PARSE_KEY
  1538.                POP     BP
  1539.                POP     BX
  1540.                JC      NEXT_NUM2
  1541.  
  1542.                CALL    PARSE_LINE
  1543.                JC      NEXT_NUM2
  1544.                CMP     BYTE PTR [SI],"-"
  1545.                JNZ     GET_LOW
  1546.                INC     SI
  1547.                JMP     SHORT GET_HIGH
  1548. GET_LOW:       CALL    PARSE_LINE
  1549.                JC      NEXT_NUM2
  1550.                CALL    GET_NUMBER
  1551.                JC      NEXT_NUM2
  1552.                MOV     CS:RANGE_LOW[BX],AX
  1553.  
  1554. GET_HIGH:      CALL    PARSE_LINE
  1555.                JC      NEXT_NUM2
  1556.                CALL    GET_NUMBER
  1557.                JC      NEXT_NUM2
  1558.                MOV     CS:RANGE_HIGH[BX],AX
  1559.  
  1560. NEXT_NUM2:     INC     BX
  1561.                INC     BX
  1562.                CMP     BX,NUM_MAX * 2
  1563.                JAE     N_END
  1564.                CALL    PARSE_END2
  1565.                CALL    PARSE_LINES
  1566.                JC      N_END2
  1567.                JMP     NEXT_NUM
  1568.  
  1569. N_END2:        CLC
  1570.  
  1571. N_END:         RET
  1572.  
  1573. ;----------------------------------------------;
  1574. ; INPUT: DS:SI-> String  OUTPUT: CF=1 if no string.
  1575.  
  1576. PARSE_STRING:  MOV     AH,DOUBLE_QUOTES
  1577.                CMP     BYTE PTR [SI],AH
  1578.                JNZ     NO_STRING
  1579.                INC     SI
  1580. NEXT_STRING:   LODSB
  1581.                CMP     AL,CTRL_Z
  1582.                JZ      NO_STRING1
  1583.                CMP     AL,CR
  1584.                JZ      NO_STRING
  1585.                CMP     AL,AH
  1586.                JNZ     NEXT_STRING
  1587.                MOV     BYTE PTR [SI-1],0       ;ASCIIZ string
  1588.                CLC
  1589.                JMP     SHORT STRING_END
  1590.  
  1591. NO_STRING1:    DEC     SI
  1592. NO_STRING:     STC
  1593. STRING_END:    RET
  1594.  
  1595. ;----------------------------------------------;
  1596. ; INPUT:  ES:BX->string to match; BP=string len; DS:SI-> FILEBUFF.
  1597. ; OUTPUT: CF=1 if no match; CF=0 if match; SI-> next string.
  1598.  
  1599. PARSE_KEY:     MOV     AL,[SI]
  1600.                CMP     AL,CTRL_Z
  1601.                JZ      NO_KEY
  1602.                CMP     AL,"["
  1603.                JZ      NO_KEY
  1604.  
  1605.                MOV     CX,BP
  1606.                MOV     DI,BX
  1607.                MOV     AX,SI
  1608.                REP     CMPSB
  1609.                JZ      FOUND_KEY
  1610.                MOV     SI,AX
  1611.                PUSH    BX
  1612.                CALL    PARSE_END2
  1613.                CALL    PARSE_LINES
  1614.                POP     BX
  1615.                JMP     PARSE_KEY
  1616.  
  1617. FOUND_KEY:     CALL    PARSE_LINE
  1618.                RET
  1619.  
  1620. NO_KEY:        STC
  1621.                RET
  1622.  
  1623. ;----------------------------------------------;
  1624. PARSE_END2:    LODSB
  1625.                CMP     AL,LF
  1626.                JZ      PARSE_END_END
  1627.                CMP     AL,CTRL_Z
  1628.                JNZ     PARSE_END2
  1629.                DEC     SI
  1630. PARSE_END_END: RET
  1631.  
  1632. ;--------------;
  1633. PICK_M1        LABEL BYTE
  1634. DB "Select pick description then press Enter to pick.                    Esc to Exit",0
  1635.  
  1636. PICK_M         DB      "Pick descriptions",0
  1637.                DB      "~~~~~~~~~~~~~~~~~",0
  1638.  
  1639. PICK_INDEX     DW      ?
  1640.  
  1641.  
  1642. PICK_MENU:     CMP     [PICK_MENUS],INACTIVE
  1643.                JZ      P_MENU_END1
  1644.                MOV     PICK_INDEX,0
  1645.  
  1646. NEXT_P_MENU:   MOV     STATE,CUSTOM_TYPE
  1647.                MOV     SI,OFFSET PICK_M1
  1648.                CALL    DISPLAY_MENU
  1649.  
  1650. NEXT_P_MENU2:  CALL    DISP_PICK
  1651.                CALL    GETKEY
  1652.                JC      P_MENU_END
  1653.                CMP     AL,LEFT_SCAN
  1654.                JZ      P_MENU_END
  1655.  
  1656.                CMP     AH,CR
  1657.                JZ      DO_PICK
  1658.                CMP     AL,RIGHT_SCAN
  1659.                JZ      DO_PICK
  1660.  
  1661. CK_P_UP:       MOV     BX,PICK_INDEX
  1662.                CMP     AL,UP_SCAN
  1663.                JNZ     CK_P_DN
  1664.                SUB     BX,2
  1665.                JC      NEXT_P_MENU2
  1666.                JMP     SHORT PICK_UPDATE
  1667.  
  1668. CK_P_DN:       CMP     AL,DOWN_SCAN
  1669.                JNZ     NEXT_P_MENU2
  1670.                INC     BX
  1671.                INC     BX
  1672.                CMP     BX,PICK_MAX * 2
  1673.                JAE     NEXT_P_MENU2
  1674.                CMP     PICK_MENUS[BX],INACTIVE
  1675.                JZ      NEXT_P_MENU2
  1676. PICK_UPDATE:   MOV     PICK_INDEX,BX
  1677.                JMP     NEXT_P_MENU2
  1678.  
  1679. DO_PICK:       CALL    PICK_SELECT
  1680.                JMP     NEXT_P_MENU
  1681.  
  1682. P_MENU_END1:   CALL    BEEP
  1683. P_MENU_END:    RET
  1684.  
  1685. ;----------------------------------------------;
  1686. DISP_PICK:     MOV     AX,PICK_TOP
  1687.                CALL    CALC_ADDR
  1688.                ADD     DI,SELECT_START
  1689.                MOV     BH,COLOR.W
  1690.  
  1691.                PUSH    DI
  1692.                MOV     SI,OFFSET PICK_M
  1693.                CALL    WRITE_STRING
  1694.                POP     DI
  1695.                ADD     DI,CRT_WIDTH
  1696.  
  1697.                PUSH    DI
  1698.                CALL    WRITE_STRING
  1699.                POP     DI
  1700.  
  1701. ;--------------;
  1702.                XOR     BP,BP
  1703. NEXT_PICK_DES: MOV     SI,PICK_MENUS[BP]
  1704.                CMP     SI,INACTIVE
  1705.                JZ      PICK_DES_END
  1706.                ADD     DI,CRT_WIDTH
  1707.                PUSH    DI
  1708.  
  1709.                MOV     CX,STRING_MAX
  1710.                MOV     BH,COLOR.W
  1711.                CMP     PICK_INDEX,BP
  1712.                JNZ     WRITE_DESC4
  1713.                MOV     BH,COLOR.C
  1714.                CMP     STATE,CUSTOM_TYPE
  1715.                JZ      WRITE_DESC4
  1716.                MOV     BH,COLOR.A
  1717.  
  1718. WRITE_DESC4:   PUSH    DS
  1719.                MOV     DS,ZIF_BUFF_SEG
  1720.                CALL    WRITE_LINE
  1721.                CALL    PAD_LINE
  1722.                POP     DS
  1723.                POP     DI
  1724.                INC     BP
  1725.                INC     BP
  1726.                CMP     BP,PICK_MAX * 2
  1727.                JB      NEXT_PICK_DES
  1728.  
  1729. PICK_DES_END:  RET
  1730.  
  1731. ;----------------------------------------------;
  1732. PICK_M2        LABEL BYTE
  1733. DB "Pick entry then press Enter to select.                             Esc to Cancel",0
  1734.  
  1735. ENTRY_SELECT_HOME      DW ?
  1736. ENTRY_SELECT_INDEX     DW ?
  1737.  
  1738. PICK_SELECT:   MOV     STATE,SELECT_TYPE
  1739.                MOV     SI,OFFSET PICK_M2
  1740.                CALL    DISPLAY_MENU
  1741.                CALL    DISP_PICK
  1742.  
  1743.                MOV     AX,PICK_MAX
  1744.                MOV     BX,PICK_INDEX           ;BX=Pick index.
  1745.                MUL     BX
  1746.                MOV     BP,AX                   ;BP=Entry index.
  1747.                MOV     ENTRY_SELECT_HOME,BP
  1748.  
  1749.                MOV     SI,PICK_ADDRS[BX]
  1750.                PUSH    DS
  1751.                MOV     DS,PGM_BUFF_SEG
  1752.                MOV     AX,[SI]                  ;Current value.
  1753.                POP     DS
  1754.  
  1755. NEXT_P_DEF:    CMP     CS:ENTRY_MENUS[BP],INACTIVE
  1756.                JZ      FOUND_DEF1
  1757.                CMP     BYTE PTR PICK_TYPES[BX],"W"
  1758.                JZ      CK_WORD
  1759.                CMP     BYTE PTR CS:ENTRY_VALUES[BP],AL
  1760.                JZ      FOUND_DEF
  1761.                JMP     SHORT LOOP_DEF
  1762. CK_WORD:       CMP     CS:ENTRY_VALUES[BP],AX
  1763.                JZ      FOUND_DEF
  1764. LOOP_DEF:      INC     SI
  1765.                INC     SI
  1766.                INC     BP
  1767.                INC     BP
  1768.                JMP     NEXT_P_DEF
  1769.  
  1770. FOUND_DEF1:    DEC     BP
  1771.                DEC     BP
  1772.  
  1773. FOUND_DEF:     MOV     ENTRY_SELECT_INDEX,BP
  1774.  
  1775. NEXT_P_SEL:    CALL    DISP_SELECT
  1776.                CALL    GETKEY
  1777.                JC      PICK_S_END
  1778.                CMP     AL,LEFT_SCAN
  1779.                JZ      PICK_S_END
  1780.  
  1781.                CMP     AH,CR
  1782.                JZ      DO_S_PICK
  1783.  
  1784. CK_S_UP:       MOV     BX,ENTRY_SELECT_INDEX
  1785.                CMP     AL,UP_SCAN
  1786.                JNZ     CK_S_DN
  1787.                SUB     BX,2
  1788.                JC      NEXT_P_SEL
  1789.                CMP     BX,ENTRY_SELECT_HOME
  1790.                JB      NEXT_P_SEL
  1791.                JMP     SHORT ENTRY_UPDATE
  1792.  
  1793. CK_S_DN:       CMP     AL,DOWN_SCAN
  1794.                JNZ     NEXT_P_SEL
  1795.                INC     BX
  1796.                INC     BX
  1797.                CMP     ENTRY_MENUS[BX],INACTIVE
  1798.                JZ      NEXT_P_SEL
  1799. ENTRY_UPDATE:  MOV     ENTRY_SELECT_INDEX,BX
  1800.                JMP     NEXT_P_SEL
  1801.  
  1802. DO_S_PICK:     MOV     MODIFY_FLAG,TRUE
  1803.  
  1804. PICK_S_END:    CALL    CK_MODIFIED
  1805.                JC      P_S_END
  1806.                CALL    COPY_PICK
  1807.                CALL    SAVE
  1808. P_S_END:       CALL    CLEAR_PICK
  1809.                RET
  1810.  
  1811. ;----------------------;
  1812. DISP_SELECT:   MOV     AX,PICK_INDEX
  1813.                SHR     AX,1
  1814.                ADD     AX,PICK_TOP + 2
  1815.                CALL    CALC_ADDR
  1816.                ADD     DI,SELECT_START + (STRING_MAX * 2)
  1817.  
  1818.                MOV     BP,ENTRY_SELECT_HOME
  1819. NEXT_SEL_DES:  MOV     SI,ENTRY_MENUS[BP]
  1820.                CMP     SI,INACTIVE
  1821.                JZ      SELECT_DES_END
  1822.                PUSH    DI
  1823.  
  1824.                MOV     CX,STRING_MAX
  1825.                MOV     BH,COLOR.W
  1826.                CMP     ENTRY_SELECT_INDEX,BP
  1827.                JNZ     WRITE_DESC6
  1828.                MOV     BH,COLOR.C
  1829.  
  1830. WRITE_DESC6:   PUSH    DS
  1831.                MOV     DS,ZIF_BUFF_SEG
  1832.                CALL    WRITE_LINE
  1833.                CALL    PAD_LINE
  1834.                POP     DS
  1835.                POP     DI
  1836.                ADD     DI,CRT_WIDTH
  1837.                INC     BP
  1838.                INC     BP
  1839.                JMP     NEXT_SEL_DES
  1840.  
  1841. SELECT_DES_END:RET
  1842.  
  1843. ;----------------------------------------------;
  1844. COPY_PICK:     PUSH    ES
  1845.                MOV     ES,PGM_BUFF_SEG
  1846.                MOV     SI,PICK_INDEX
  1847.                MOV     DI,PICK_ADDRS[SI]
  1848.                CMP     BYTE PTR PICK_TYPES[SI],"W"
  1849.                MOV     SI,ENTRY_SELECT_INDEX
  1850.                MOV     AX,ENTRY_VALUES[SI]
  1851.                JZ      COPY_WORD2
  1852.                STOSB
  1853.                JMP     SHORT COPY_P_END
  1854. COPY_WORD2:    STOSW
  1855. COPY_P_END:    POP     ES
  1856.                RET
  1857.  
  1858. ;----------------------------------------------;
  1859. CLEAR_PICK:    MOV     AX,PICK_INDEX
  1860.                SHR     AX,1
  1861.                ADD     AX,PICK_TOP + 2
  1862.                CALL    CALC_ADDR
  1863.                ADD     DI,SELECT_START + (STRING_MAX * 2)
  1864.  
  1865.                PUSH    ES
  1866.                MOV     DX,STATUS_REG           ;Retrieve status register.
  1867.                MOV     ES,VIDEO_SEG            ;Point to screen segment.
  1868.                MOV     SI,COLOR_INDEX
  1869.                MOV     BH,COLOR.W
  1870.                MOV     AL,SPACE
  1871.  
  1872.                MOV     BP,PICK_MAX
  1873. NEXT_CLEAR5:   PUSH    DI
  1874.                MOV     CX,STRING_MAX
  1875. NEXT_CLEAR6:   CALL    WRITE_CHAR
  1876.                LOOP    NEXT_CLEAR6
  1877.                POP     DI
  1878.                ADD     DI,CRT_WIDTH
  1879.                DEC     BP
  1880.                JNZ     NEXT_CLEAR5
  1881.                POP     ES
  1882.                RET
  1883.  
  1884. ;----------------------------------------------;
  1885. COLOR_M1 LABEL BYTE
  1886. DB "Select color description then press Enter to change color.           Esc to Exit",0
  1887.  
  1888. COLOR_M        DB      "Color Descriptions",0
  1889.                DB      "~~~~~ ~~~~~~~~~~~~",0
  1890.  
  1891. COLOR_INDEX    DW      0
  1892.  
  1893.  
  1894. COLOR_MENU:    CMP     [COLOR_MENUS],INACTIVE
  1895.                JZ      C_MENU_END1
  1896.                CALL    COLOR_DEFAULT
  1897.                MOV     COLOR_INDEX,0
  1898.  
  1899. NEXT_C_MENU:   MOV     STATE,CUSTOM_TYPE
  1900.                MOV     SI,OFFSET COLOR_M1
  1901.                CALL    DISPLAY_MENU
  1902.  
  1903. NEXT_C_MENU2:  CALL    DISP_COLOR
  1904.                CALL    GETKEY
  1905.                JC      C_MENU_END
  1906.                CMP     AL,LEFT_SCAN
  1907.                JZ      C_MENU_END
  1908.  
  1909.                CMP     AH,CR
  1910.                JZ      DO_COLOR
  1911.                CMP     AL,RIGHT_SCAN
  1912.                JZ      DO_COLOR
  1913.  
  1914. CK_C_UP:       MOV     BX,COLOR_INDEX
  1915.                CMP     AL,UP_SCAN
  1916.                JNZ     CK_C_DN
  1917.                SUB     BX,2
  1918.                JC      NEXT_C_MENU2
  1919.                JMP     SHORT COLOR_UPDATE
  1920.  
  1921. CK_C_DN:       CMP     AL,DOWN_SCAN
  1922.                JNZ     NEXT_C_MENU2
  1923.                INC     BX
  1924.                INC     BX
  1925.                CMP     BX,COLOR_MAX * 2
  1926.                JAE     NEXT_C_MENU2
  1927.                CMP     COLOR_MENUS[BX],INACTIVE
  1928.                JZ      NEXT_C_MENU2
  1929. COLOR_UPDATE:  MOV     COLOR_INDEX,BX
  1930.                JMP     NEXT_C_MENU2
  1931.  
  1932. DO_COLOR:      CALL    COLOR_SELECT
  1933.                JMP     NEXT_C_MENU
  1934.  
  1935. C_MENU_END1:   CALL    BEEP
  1936. C_MENU_END:    CALL    CK_MODIFIED
  1937.                JC      C_M_END
  1938.                CALL    COPY_COLORS
  1939.                CALL    SAVE
  1940. C_M_END:       RET
  1941.  
  1942. ;--------------;
  1943.  
  1944. COLOR_DEFAULT: PUSH    ES
  1945.                MOV     ES,PGM_BUFF_SEG
  1946.                XOR     BX,BX
  1947. NEXT_C_DEFAULT:CMP     [COLOR_MENUS.BX],INACTIVE
  1948.                JZ      C_DEFAULT_END
  1949.                MOV     SI,[COLOR_ADDRS.BX]
  1950.                MOV     AX,ES:[SI]
  1951.                MOV     [COLOR_VALUES.BX],AX
  1952.                INC     BX
  1953.                INC     BX
  1954.                CMP     BX,COLOR_MAX * 2
  1955.                JB      NEXT_C_DEFAULT
  1956. C_DEFAULT_END: POP     ES
  1957.                RET
  1958.  
  1959. ;--------------;
  1960.  
  1961. DISP_COLOR:    PUSH    DS
  1962.  
  1963.                MOV     AX,COLOR_TOP
  1964.                CALL    CALC_ADDR
  1965.                ADD     DI,SELECT_START
  1966.                MOV     BH,COLOR.W
  1967.  
  1968.                PUSH    DI
  1969.                MOV     SI,OFFSET COLOR_M
  1970.                CALL    WRITE_STRING
  1971.                POP     DI
  1972.                ADD     DI,CRT_WIDTH
  1973.  
  1974.                PUSH    DI
  1975.                CALL    WRITE_STRING
  1976.                POP     DI
  1977.  
  1978. ;--------------;
  1979.                XOR     BP,BP
  1980.                MOV     DS,ZIF_BUFF_SEG
  1981.  
  1982. NEXT_COLOR_DES:MOV     SI,CS:COLOR_MENUS[BP]
  1983.                CMP     SI,INACTIVE
  1984.                JZ      COLOR_DES_END
  1985.                ADD     DI,CS:CRT_WIDTH
  1986.                PUSH    DI
  1987.  
  1988.                MOV     BX,CS:COLOR_VALUES[BP]
  1989.                XCHG    BH,BL
  1990.                MOV     AL,SPACE
  1991.                CALL    WRITE_SCREEN
  1992.                MOV     AL,"["
  1993.                CALL    WRITE_SCREEN
  1994.                MOV     AX,BP
  1995.                SHR     AX,1
  1996.                ADD     AL,"A"
  1997.                CALL    WRITE_SCREEN
  1998.                MOV     AL,"]"
  1999.                CALL    WRITE_SCREEN
  2000.                MOV     AL,SPACE
  2001.                CALL    WRITE_SCREEN
  2002.                MOV     BH,CS:COLOR.W
  2003.                CALL    WRITE_SCREEN
  2004.  
  2005.                CMP     CS:COLOR_INDEX,BP
  2006.                JNZ     WRITE_DESC
  2007.                MOV     BH,CS:COLOR.C
  2008.                CMP     CS:STATE,CUSTOM_TYPE
  2009.                JZ      WRITE_DESC
  2010.                MOV     BH,CS:COLOR.A
  2011. WRITE_DESC:    CALL    WRITE_STRING
  2012.  
  2013.                POP     DI
  2014.                INC     BP
  2015.                INC     BP
  2016.                CMP     BP,COLOR_MAX * 2
  2017.                JB      NEXT_COLOR_DES
  2018.  
  2019. COLOR_DES_END: POP     DS
  2020.                RET
  2021.  
  2022. ;----------------------------------------------;
  2023. COLOR_M2       LABEL   BYTE
  2024. DB "Select color then press Enter.                                     Esc to Cancel",0
  2025.  
  2026. COLOR_SELECT:  MOV     SI,COLOR_INDEX
  2027.                PUSH    COLOR_VALUES[SI]
  2028.  
  2029.                MOV     STATE,SELECT_TYPE
  2030.                MOV     SI,OFFSET COLOR_M2
  2031.                CALL    DISPLAY_MENU
  2032. NEXT_C_BARS:   CALL    DISP_COLOR
  2033.  
  2034.                MOV     AX,COLOR_TOP + COLOR_MAX + 2
  2035.                CALL    CALC_ADDR
  2036.                ADD     DI,SELECT_START
  2037.  
  2038.                PUSH    ES
  2039.                MOV     DX,STATUS_REG           ;Retrieve status register.
  2040.                MOV     ES,VIDEO_SEG            ;Point to screen segment.
  2041.                MOV     SI,COLOR_INDEX
  2042.                XOR     BH,BH
  2043.  
  2044. N_BACKGROUND:  PUSH    DI
  2045. N_FORGROUND:   MOV     AL,SPACE
  2046.                CALL    WRITE_CHAR
  2047.                MOV     AL,"*"
  2048.                CMP     BH,BYTE PTR COLOR_VALUES[SI]
  2049.                JNZ     DO_A_COLOR
  2050.                MOV     AX,COLOR_INDEX
  2051.                SHR     AL,1
  2052.                ADD     AL,"A"
  2053. DO_A_COLOR:    CALL    WRITE_CHAR
  2054.                MOV     AL,SPACE
  2055.                CALL    WRITE_CHAR
  2056.                INC     BH
  2057.                TEST    BH,1111B
  2058.                JNZ     N_FORGROUND
  2059.                POP     DI
  2060.                ADD     DI,CRT_WIDTH
  2061.                TEST    BH,10000000B
  2062.                JZ      N_BACKGROUND
  2063.                POP     ES
  2064.  
  2065. NEXT_C_KEY:    CALL    GETKEY
  2066.                JC      COLOR_S_END1
  2067.                CMP     AH,CR
  2068.                JZ      SELECT_ENTER
  2069.  
  2070.                MOV     CX,COLOR_VALUES[SI]
  2071.                MOV     BH,CL
  2072.                MOV     BL,CL
  2073.                AND     BH,11110000B            ;Background
  2074.                AND     BL,00001111B            ;Foreground
  2075.                CMP     AL,UP_SCAN
  2076.                JNZ     CK_COLOR_DN
  2077.                SUB     BH,00010000B
  2078.                JC      NEXT_C_KEY
  2079.                JMP     SHORT UPDATE_C
  2080.  
  2081. CK_COLOR_DN:   CMP     AL,DOWN_SCAN
  2082.                JNZ     CK_COLOR_RT
  2083.                ADD     BH,00010000B
  2084.                TEST    BH,10000000B
  2085.                JNZ     NEXT_C_KEY
  2086.                JMP     SHORT UPDATE_C
  2087.  
  2088. CK_COLOR_RT:   CMP     AL,RIGHT_SCAN
  2089.                JNZ     CK_COLOR_LT
  2090.                ADD     BL,1
  2091.                TEST    BL,00010000B
  2092.                JNZ     NEXT_C_KEY
  2093.                JMP     SHORT UPDATE_C
  2094.  
  2095. CK_COLOR_LT:   CMP     AL,LEFT_SCAN
  2096.                JNZ     NEXT_C_KEY
  2097.                SUB     BL,1
  2098.                JC      NEXT_C_KEY
  2099.  
  2100. UPDATE_C:      OR      BL,BH
  2101.                MOV     CL,BL
  2102.                MOV     COLOR_VALUES[SI],CX
  2103.                JMP     NEXT_C_BARS
  2104.  
  2105. SELECT_ENTER:  POP     AX
  2106.                MOV     MODIFY_FLAG,TRUE
  2107.                JMP     SHORT COLOR_S_END
  2108.  
  2109. COLOR_S_END1:  MOV     SI,COLOR_INDEX
  2110.                POP     COLOR_VALUES[SI]
  2111. COLOR_S_END:   CALL    CLEAR_BARS
  2112.                RET
  2113.  
  2114. ;----------------------------------------------;
  2115.  
  2116. CLEAR_BARS:    MOV     AX,COLOR_TOP + COLOR_MAX + 2
  2117.                CALL    CALC_ADDR
  2118.                ADD     DI,SELECT_START
  2119.  
  2120.                PUSH    ES
  2121.                MOV     DX,STATUS_REG           ;Retrieve status register.
  2122.                MOV     ES,VIDEO_SEG            ;Point to screen segment.
  2123.                MOV     SI,COLOR_INDEX
  2124.                MOV     BH,COLOR.W
  2125.                MOV     AL,SPACE
  2126.  
  2127.                MOV     BP,8
  2128. NEXT_CLEAR3:   PUSH    DI
  2129.                MOV     CX,16 * 3
  2130. NEXT_CLEAR4:   CALL    WRITE_CHAR
  2131.                LOOP    NEXT_CLEAR4
  2132.                POP     DI
  2133.                ADD     DI,CRT_WIDTH
  2134.                DEC     BP
  2135.                JNZ     NEXT_CLEAR3
  2136.                POP     ES
  2137.                RET
  2138.  
  2139. ;----------------------------------------------;
  2140. COPY_COLORS:   PUSH    ES
  2141.                MOV     ES,PGM_BUFF_SEG
  2142.                XOR     BX,BX
  2143. NEXT_C_COPY:   CMP     COLOR_MENUS[BX],INACTIVE
  2144.                JZ      COPY_C_END
  2145.                MOV     DI,COLOR_ADDRS[BX]
  2146.                MOV     AX,COLOR_VALUES[BX]
  2147.                STOSB
  2148.                INC     BX
  2149.                INC     BX
  2150.                JMP     NEXT_C_COPY
  2151. COPY_C_END:    POP     ES
  2152.                RET
  2153.  
  2154. ;----------------------------------------------;
  2155. SCAN_CODES LABEL BYTE
  2156.  
  2157. DB "1",2,"2",3,"3",4,"4",5,"5",6,"6",7,"7",8,"8",9,"9",0AH,"0",0BH,"-",0CH
  2158. DB "=",0DH,"Q",10H,"W",11H,"E",12H,"R",13H,"T",14H,"Y",15H,"U",16H,"I",17H
  2159. DB "O",18H,"P",19H,"[",1AH,"]",1BH,"A",1EH,"S",1FH,"D",20H,"F",21H,"G",22H
  2160. DB "H",23H,"J",24H,"K",25H,"L",26H,";",27H,39,28H,96,29H,"\",2BH,"Z",2CH
  2161. DB "X",2DH,"C",2EH,"V",2FH,"B",30H,"N",31H,"M",32H,",",33H,".",34H,"/",35H
  2162.  
  2163. SCAN_COUNT     EQU     ($ - SCAN_CODES) / 2
  2164.  
  2165.  
  2166. ;--------------;
  2167. HOT_MENU       LABEL BYTE
  2168. DB "Current hotkey is ",0
  2169. HOT_MENU2      LABEL BYTE
  2170. DB "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",0
  2171.  
  2172. HOT_MENU3      LABEL   BYTE
  2173. DB "Select HotKey and then press Enter.                                Esc to cancel",0
  2174.  
  2175. HOT_MENU4      LABEL BYTE
  2176. DB "Select Shift key and then press Enter.                             Esc to cancel",0
  2177.  
  2178. HOT_MENU5      LABEL   BYTE
  2179. DB "Press Alpha or Numeric key.                                        Esc to cancel",0
  2180.  
  2181. SHIFT_TEXT     DB "CtRs", "CtLs", "AlRs", "AlLs", "RsLs", "CtAl"
  2182. CTRL           DB "Ctrl ",0
  2183. ALT            DB "Alt ",0
  2184. RT_SHIFT       DB "Right Shift ",0
  2185. LT_SHIFT       DB "Left Shift ",0
  2186.  
  2187.  
  2188. SHIFT_COMBOS   LABEL   BYTE
  2189. DB  CTRL_KEY + RIGHT_SHIFT, CTRL_KEY + LEFT_SHIFT,    ALT_KEY + RIGHT_SHIFT
  2190. DB  ALT_KEY  + LEFT_SHIFT,  RIGHT_SHIFT + LEFT_SHIFT, CTRL_KEY + ALT_KEY
  2191. COMBOS_LEN     EQU $ - SHIFT_COMBOS
  2192.  
  2193. SHIFT_KEY      DB      ?
  2194. SHIFT_INDEX    DW      ?
  2195. HOTKEY         LABEL   WORD
  2196. SCAN_TEXT      DB      ?
  2197. SCAN_KEY       DB      ?
  2198.  
  2199. HOTKEY_MENU:   MOV     SI,OFFSET HOT_MENU3
  2200.                CMP     SCAN_ADDR,INACTIVE
  2201.                JZ      DISP_HOT_M
  2202.                MOV     SI,OFFSET HOT_MENU4
  2203. DISP_HOT_M:    CALL    DISPLAY_MENU
  2204.  
  2205.                MOV     AX,HOT_TOP
  2206.                CALL    CALC_ADDR
  2207.                ADD     DI,SELECT_START
  2208.                MOV     BP,DI
  2209.                MOV     BH,COLOR.W
  2210.  
  2211.                MOV     SI,OFFSET HOT_MENU
  2212.                CALL    WRITE_STRING
  2213.  
  2214.                MOV     SI,SHIFT_ADDR
  2215.                PUSH    DS
  2216.                MOV     DS,PGM_BUFF_SEG
  2217.                MOV     AL,[SI]                 ;Shift key
  2218.                MOV     SI,CS:SCAN_ADDR
  2219.                MOV     AH,[SI]                 ;AlphaNumeric key
  2220.                POP     DS
  2221.                MOV     SHIFT_KEY,AL
  2222.                CMP     SI,INACTIVE
  2223.                JNZ     SHIFT_ALPHA
  2224.  
  2225. SHIFT_ONLY:    CALL    DISP_COMBOS
  2226.                ADD     BP,CRT_WIDTH
  2227.                MOV     DI,BP
  2228.                MOV     SI,OFFSET HOT_MENU2
  2229.                CALL    WRITE_STRING
  2230.                ADD     BP,CRT_WIDTH
  2231.  
  2232.                MOV     AL,SHIFT_KEY
  2233.                MOV     DI,OFFSET SHIFT_COMBOS
  2234.                MOV     CX,COMBOS_LEN
  2235.                REPNZ   SCASB
  2236.                NEG     CX
  2237.                ADD     CX,COMBOS_LEN - 1
  2238.                MOV     SHIFT_INDEX,CX
  2239.  
  2240. ;--------------;
  2241. NEXT_SH_ONLY:  MOV     DI,BP
  2242.                XOR     SI,SI
  2243. NEXT_SH_ONLY2: MOV     AL,SHIFT_COMBOS[SI]
  2244.                MOV     BH,COLOR.C
  2245.                CMP     AL,SHIFT_KEY
  2246.                JZ      DISP_SHIFT
  2247.                MOV     BH,COLOR.W
  2248. DISP_SHIFT:    PUSH    SI
  2249.                PUSH    DI
  2250.                CALL    DISP_COMBOS
  2251.                POP     DI
  2252.                POP     SI
  2253.                ADD     DI,CRT_WIDTH
  2254.                INC     SI
  2255.                CMP     SI,COMBOS_LEN
  2256.                JB      NEXT_SH_ONLY2
  2257.  
  2258.                CALL    SHIFT_HOT
  2259.                JNC     NEXT_SH_ONLY
  2260.                JMP     HOT_DONE1
  2261.  
  2262. ;--------------;
  2263. SHIFT_ALPHA:   CALL    DISP_COMBOS
  2264.                XCHG    AH,AL
  2265.                CALL    SCAN_LOOKUP
  2266.                CALL    WRITE_SCREEN
  2267.                ADD     BP,CRT_WIDTH
  2268.                MOV     DI,BP
  2269.                MOV     SI,OFFSET HOT_MENU2
  2270.                CALL    WRITE_STRING
  2271.                ADD     BP,CRT_WIDTH
  2272.  
  2273. NEXT_S_ALPHA:  MOV     DI,BP
  2274.                MOV     SI,OFFSET CTRL
  2275.                MOV     BH,COLOR.C
  2276.                CMP     SHIFT_KEY,CTRL_KEY
  2277.                JZ      DISP_CTRL
  2278.                MOV     BH,COLOR.W
  2279. DISP_CTRL:     CALL    WRITE_STRING
  2280.                MOV     DI,BP
  2281.                ADD     DI,CRT_WIDTH
  2282.  
  2283.                MOV     SI,OFFSET ALT
  2284.                MOV     BH,COLOR.C
  2285.                CMP     SHIFT_KEY,ALT_KEY
  2286.                JZ      DISP_ALT
  2287.                MOV     BH,COLOR.W
  2288. DISP_ALT:      CALL    WRITE_STRING
  2289.  
  2290. NEXT_S_ALPHA2: CALL    GETKEY
  2291.                JC      HOT_DONE1
  2292.                CMP     AL,LEFT_SCAN
  2293.                JZ      HOT_DONE1
  2294.                CMP     AH,CR
  2295.                JZ      HOT_ALPHA
  2296.                CMP     AL,UP_SCAN
  2297.                JNZ     CK_ALPHA_DN
  2298.                MOV     SHIFT_KEY,CTRL_KEY
  2299.                JMP     NEXT_S_ALPHA
  2300. CK_ALPHA_DN:   CMP     AL,DOWN_SCAN
  2301.                JNZ     NEXT_S_ALPHA2
  2302.                MOV     SHIFT_KEY,ALT_KEY
  2303.                JMP     NEXT_S_ALPHA
  2304.  
  2305. ;--------------;
  2306. HOT_ALPHA:     MOV     SI,OFFSET HOT_MENU5
  2307.                CALL    DISPLAY_MENU
  2308.                MOV     DH,HOT_TOP + 4
  2309.                MOV     DL,SELECT_START SHR 1
  2310.                CALL    SET_CURSOR
  2311.                ADD     BP,CRT_WIDTH
  2312.                ADD     BP,CRT_WIDTH
  2313.  
  2314. NEXT_ALPHA:    CALL    GETKEY
  2315.                JC      HOT_DONE1
  2316.                CMP     AL,LEFT_SCAN
  2317.                JZ      HOT_DONE1
  2318.                CALL    SCAN_LOOKUP
  2319.                JCXZ    NEXT_ALPHA
  2320.                MOV     HOTKEY,AX
  2321.                MOV     DI,BP
  2322.                MOV     BH,COLOR.C
  2323.                CALL    WRITE_SCREEN
  2324.                MOV     MODIFY_FLAG,1
  2325.  
  2326. HOT_DONE1:     CALL    HIDE_CURSOR
  2327.                CALL    CK_MODIFIED
  2328.                JC      HOT_DONE
  2329.                CALL    COPY_HOT
  2330.                CALL    SAVE
  2331.  
  2332. HOT_DONE:      RET
  2333.  
  2334. ;--------------;
  2335. SCAN_LOOKUP:   PUSH    ES
  2336.                PUSH    DI
  2337.                MOV     CX,CS
  2338.                MOV     ES,CX
  2339.                MOV     DI,OFFSET SCAN_CODES + 1
  2340.                MOV     CX,SCAN_COUNT          ;38 possible Alt key combos.
  2341. NEXT_SCAN2:    SCASB                         ;Do we have a match?
  2342.                JZ      GOT_HOT
  2343.                INC     DI                     ;If no, bump pointer to next byte.
  2344.                LOOP    NEXT_SCAN2
  2345. GOT_HOT:       MOV     AH,AL
  2346.                MOV     AL,[DI - 2]
  2347.                POP     DI
  2348.                POP     ES
  2349.                RET
  2350.  
  2351. ;----------------------------------------------;
  2352. ;INPUT: AL=shift state; DI->screen; BH=color
  2353.  
  2354. DISP_COMBOS:   PUSH    AX
  2355.                MOV     CX,AX
  2356.                MOV     SI,OFFSET CTRL
  2357.                TEST    AL,CTRL_KEY
  2358.                JZ      CK_ALT
  2359.                CALL    WRITE_STRING
  2360. CK_ALT:        MOV     SI,OFFSET ALT
  2361.                TEST    CL,ALT_KEY
  2362.                JZ      CK_RT_SHIFT
  2363.                CALL    WRITE_STRING
  2364. CK_RT_SHIFT:   MOV     SI,OFFSET RT_SHIFT
  2365.                TEST    CL,RIGHT_SHIFT
  2366.                JZ      CK_LF_SHIFT
  2367.                CALL    WRITE_STRING
  2368. CK_LF_SHIFT:   MOV     SI,OFFSET LT_SHIFT
  2369.                TEST    CL,LEFT_SHIFT
  2370.                JZ      SHIFT_DONE
  2371.                CALL    WRITE_STRING
  2372. SHIFT_DONE:    POP     AX
  2373.                RET
  2374.  
  2375. ;----------------------------------------------;
  2376. SHIFT_HOT:     CALL    GETKEY
  2377.                JC      SHIFT_HOT_END
  2378.                CMP     AH,CR
  2379.                JZ      SHIFT_ENTER
  2380.                MOV     BL,SHIFT_KEY
  2381.                MOV     SI,SHIFT_INDEX
  2382.  
  2383.                CMP     AL,UP_SCAN
  2384.                JNZ     CK_SHIFT_DN
  2385.                SUB     SI,1
  2386.                JC      SHIFT_HOT
  2387.                JMP     SHORT SHIFT_UPDATE
  2388.  
  2389. CK_SHIFT_DN:   CMP     AL,DOWN_SCAN
  2390.                JNZ     SHIFT_HOT
  2391.                ADD     SI,1
  2392.                CMP     SI,COMBOS_LEN
  2393.                JZ      SHIFT_HOT
  2394. SHIFT_UPDATE:  MOV     AL,SHIFT_COMBOS[SI]
  2395.                MOV     SHIFT_KEY,AL
  2396.                MOV     SHIFT_INDEX,SI
  2397.                CLC
  2398.                JMP     SHORT SHIFT_HOT_END
  2399.  
  2400. SHIFT_ENTER:   MOV     MODIFY_FLAG,1
  2401.                STC
  2402. SHIFT_HOT_END: RET
  2403.  
  2404. ;----------------------------------------------;
  2405. COPY_HOT:      PUSH    ES
  2406.  
  2407.                MOV     AL,SHIFT_KEY
  2408.                MOV     DI,OFFSET SHIFT_COMBOS
  2409.                MOV     CX,COMBOS_LEN
  2410.                REPNZ   SCASB
  2411.                NEG     CX
  2412.                ADD     CX,COMBOS_LEN - 1
  2413.                SHL     CX,1
  2414.                SHL     CX,1
  2415.                ADD     CX,OFFSET SHIFT_TEXT
  2416.                MOV     BP,CX
  2417.  
  2418.                MOV     ES,PGM_BUFF_SEG
  2419.                MOV     DI,SHIFT_ADDR
  2420.                STOSB
  2421.                MOV     DI,SHIFT_TEXT_ADDR
  2422.                CMP     DI,INACTIVE
  2423.                JZ      COPY_SCAN
  2424.  
  2425.                MOV     SI,BP
  2426.                CMP     SCAN_ADDR,INACTIVE
  2427.                JZ      COPY_S_TEXT
  2428.                MOV     SI,OFFSET CTRL
  2429.                CMP     AL,CTRL_KEY
  2430.                JZ      COPY_S_TEXT
  2431.                MOV     SI,OFFSET ALT
  2432. COPY_S_TEXT:   MOV     CX,4
  2433.                REP     MOVSB
  2434.  
  2435. COPY_SCAN:     MOV     DI,SCAN_ADDR
  2436.                CMP     DI,INACTIVE
  2437.                JZ      COPY_H_END
  2438.                MOV     AL,SCAN_KEY
  2439.                STOSB
  2440.                MOV     DI,SCAN_TEXT_ADDR
  2441.                CMP     DI,INACTIVE
  2442.                JZ      COPY_H_END
  2443.                MOV     AL,SCAN_TEXT
  2444.                STOSB
  2445.  
  2446. COPY_H_END:    POP     ES
  2447.                RET
  2448.  
  2449. ;--------------;
  2450. COM_MENU       LABEL   BYTE
  2451. DB "Enter 1, 2 or 3 for COM port.                                      Esc to cancel",0
  2452.  
  2453. COM_MENU2      LABEL   BYTE
  2454. DB "COM port: ",0
  2455.  
  2456. COM_MENU3      LABEL   BYTE
  2457. DB "  COM address: ",0
  2458.  
  2459. COM_MENU4      LABEL   BYTE
  2460. DB "Enter desired COM hexadecimal port address from your modem manual. Esc to cancel",0
  2461.  
  2462. COM_PORT       DW      ?
  2463. PORT_SCREEN    DW      ?                       ;Screen address to write port #
  2464. ADDR_SCREEN    DW      ?                       ;Screen address to write port addr.
  2465.  
  2466. COM_EDIT       DB      4 DUP (SPACE)
  2467. COM_EDIT_LEN   EQU     $ - COM_EDIT
  2468.                DB      0
  2469.  
  2470. MODEM_MENU:    MOV     SI,OFFSET COM_MENU
  2471.                CALL    DISPLAY_MENU
  2472.  
  2473.                MOV     SI,COM_ADDR
  2474.                PUSH    DS
  2475.                MOV     DS,PGM_BUFF_SEG
  2476.                MOV     CX,[SI]
  2477.                POP     DS
  2478.                MOV     COM_PORT,CX
  2479.  
  2480.                MOV     AX,COM_TOP
  2481.                CALL    CALC_ADDR
  2482.                ADD     DI,SELECT_START
  2483.                MOV     BH,COLOR.W
  2484.                MOV     SI,OFFSET COM_MENU2
  2485.                CALL    WRITE_STRING
  2486.                MOV     PORT_SCREEN,DI
  2487.                MOV     AL,"1"
  2488.                CMP     CX,3F8H
  2489.                JZ      DISP_PORT
  2490.                INC     AL
  2491.                CMP     CX,2F8H
  2492.                JZ      DISP_PORT
  2493.                INC     AL
  2494. DISP_PORT:     MOV     BH,COLOR.C
  2495.                CALL    WRITE_SCREEN
  2496.  
  2497.                MOV     BH,COLOR.W
  2498.                MOV     SI,OFFSET COM_MENU3
  2499.                CALL    WRITE_STRING
  2500.                MOV     ADDR_SCREEN,DI
  2501.                MOV     BP,CX
  2502.                MOV     BH,COLOR.C
  2503.                CALL    HEX_ASCII
  2504.  
  2505.                MOV     DH,COM_TOP
  2506.                MOV     DL,SELECT_START SHR 1 +10
  2507.                CALL    SET_CURSOR
  2508.  
  2509. NEXT_MODEM:    CALL    GETKEY
  2510.                JC      M_END1
  2511.                CMP     AH,CR
  2512.                JZ      M_END1
  2513.                CMP     AL,LEFT_SCAN
  2514.                JZ      M_END1
  2515.                CMP     AH,"1"
  2516.                JB      NEXT_MODEM
  2517.                CMP     AH,"3"
  2518.                JA      NEXT_MODEM
  2519.                MOV     AL,AH
  2520.                MOV     CL,AL
  2521.                MOV     DI,PORT_SCREEN
  2522.                MOV     BH,COLOR.C
  2523.                CALL    WRITE_SCREEN
  2524.  
  2525.                MOV     AX,3F8H
  2526.                CMP     CL,"1"
  2527.                JZ      GOT_ADDR
  2528.                MOV     AX,2F8H
  2529.                CMP     CL,"2"
  2530.                JZ      GOT_ADDR
  2531.  
  2532.                MOV     SI,OFFSET COM_MENU4
  2533.                CALL    DISPLAY_MENU
  2534.                MOV     AX,ADDR_SCREEN
  2535.                MOV     SCREEN_START,AX
  2536.                MOV     LINE_START,OFFSET COM_EDIT
  2537.                MOV     LINE_END,OFFSET COM_EDIT + COM_EDIT_LEN
  2538.                MOV     BH,COLOR.C
  2539.                MOV     LEGAL_CHARS,OFFSET NUMBER_CHARS
  2540.                CALL    EDITOR
  2541.                JC      M_END1
  2542.                CALL    CK_HEX
  2543.  
  2544.                MOV     SI,OFFSET COM_EDIT
  2545.                CALL    PARSE_LINE
  2546.                CALL    GET_NUMBER
  2547.                JC      MODEM_ERR
  2548.  
  2549. GOT_ADDR:      MOV     COM_PORT,AX
  2550.                MOV     BP,AX
  2551.                MOV     DI,ADDR_SCREEN
  2552.                MOV     BH,COLOR.C
  2553.                CALL    HEX_ASCII
  2554.  
  2555.                MOV     MODIFY_FLAG,TRUE
  2556.  
  2557. M_END1:        CALL    HIDE_CURSOR
  2558.                CALL    CK_MODIFIED
  2559.                JC      M_END
  2560.                PUSH    ES
  2561.                MOV     ES,PGM_BUFF_SEG
  2562.                MOV     DI,COM_ADDR
  2563.                MOV     AX,COM_PORT
  2564.                STOSW
  2565.                POP     ES
  2566.                CALL    SAVE
  2567.  
  2568. M_END:         RET
  2569.  
  2570. MODEM_ERR:     MOV     SI,OFFSET NUMBER_ERR
  2571.                CALL    BACKUP_ERR2
  2572.                JMP     M_END
  2573.  
  2574. ;--------------;
  2575. CK_HEX:        MOV     SI,OFFSET COM_EDIT
  2576.                MOV     CX,COM_EDIT_LEN
  2577. NEXT_CK_HEX:   LODSB
  2578.                CMP     AL,SPACE
  2579.                JBE     FOUND_HEX
  2580.                LOOP    NEXT_CK_HEX
  2581.                DEC     SI
  2582.                MOV     DI,SI
  2583.                MOV     AH,[DI]
  2584.                JMP     SHORT FOUND_HEX2
  2585.  
  2586. FOUND_HEX:     DEC     SI
  2587.                CMP     SI,OFFSET COM_EDIT
  2588.                JBE     CK_HEX_END
  2589.                MOV     DI,SI
  2590.  
  2591.                MOV     AH,[DI-1]
  2592. FOUND_HEX2:    AND     AH,5FH
  2593.                MOV     AL,"H"
  2594.                CMP     AH,AL
  2595.                JZ      CK_HEX_END
  2596.                STOSB
  2597. CK_HEX_END:    RET
  2598.  
  2599. ;-----------------------
  2600. ;INPUT: BP=number; BH=color.
  2601.  
  2602. HEX_ASCII:     MOV     CH,SPACE
  2603.                MOV     AX,BP
  2604.                MOV     AX,BP
  2605.                XCHG    AH,AL
  2606.                AND     AL,0FH
  2607.                CALL    DISP_HEX
  2608.  
  2609.                MOV     AX,BP
  2610.                MOV     CL,4
  2611.                SHR     AL,CL
  2612.                CALL    DISP_HEX
  2613.                MOV     AX,BP
  2614.                AND     AL,0FH
  2615.                CALL    DISP_HEX
  2616.                MOV     AL,"H"
  2617.                CALL    WRITE_SCREEN
  2618.                RET
  2619.  
  2620. ;--------------;
  2621. DISP_HEX:      ADD     AL,90H
  2622.                DAA
  2623.                ADC     AL,40H
  2624.                DAA
  2625.                CMP     AL,"0"
  2626.                JZ      ADJUST_HEX
  2627.                MOV     CH,"0"
  2628.                JMP     SHORT PRINT_HEX
  2629. ADJUST_HEX:    MOV     AL,CH
  2630. PRINT_HEX:     CALL    WRITE_SCREEN
  2631.                RET
  2632.  
  2633. ;--------------;
  2634. LPT_MENU       LABEL   BYTE
  2635. DB " printer addresses found.  Select printer 1"
  2636. LPT_LENGTH     EQU     $ - LPT_MENU + 1
  2637.                DB      "                       Esc to cancel",0
  2638.  
  2639. PRINTER        DB      "LPT: ",0
  2640. PRINTER_LEN    EQU     $ - PRINTER
  2641. PRINTER_CNT    DB      ?
  2642.  
  2643. PRINTER_MENU:  CALL    COUNT_PRINTERS
  2644.  
  2645.                CALL    MENU_OFFSET
  2646.                MOV     BH,COLOR.B
  2647.                PUSH    DI
  2648.                MOV     AL,PRINTER_CNT
  2649.                CALL    WRITE_SCREEN
  2650.                MOV     SI,OFFSET LPT_MENU
  2651.                CALL    WRITE_STRING
  2652.                POP     DI
  2653.  
  2654.                CMP     PRINTER_CNT,"1"
  2655.                JBE     GO_PRINTER
  2656.                ADD     DI,LPT_LENGTH * 2
  2657.                MOV     AL,"-"
  2658.                CALL    WRITE_SCREEN
  2659.                MOV     AL,PRINTER_CNT
  2660.                CALL    WRITE_SCREEN
  2661.  
  2662. GO_PRINTER:    MOV     AX,LPT_TOP
  2663.                CALL    CALC_ADDR
  2664.                ADD     DI,SELECT_START
  2665.                MOV     SI,OFFSET PRINTER
  2666.                MOV     BH,COLOR.W
  2667.                CALL    WRITE_STRING
  2668.                MOV     CX,DI
  2669.  
  2670.                MOV     SI,LPT_ADDR
  2671.                PUSH    DS
  2672.                MOV     DS,PGM_BUFF_SEG
  2673.                MOV     AL,[SI]
  2674.                POP     DS
  2675.                ADD     AL,"1"
  2676.                MOV     BH,COLOR.C
  2677.                CALL    WRITE_SCREEN
  2678.  
  2679.                MOV     DH,LPT_TOP
  2680.                MOV     DL,SELECT_START SHR 1 + PRINTER_LEN - 1
  2681.                CALL    SET_CURSOR
  2682.  
  2683. NEXT_PRINTER:  CALL    GETKEY
  2684.                JC      P_END1
  2685.                XCHG    AH,AL
  2686.                CMP     AL,CR
  2687.                JZ      P_END1
  2688.                CMP     AH,LEFT_SCAN
  2689.                JZ      P_END1
  2690.                CMP     AL,"1"
  2691.                JB      NEXT_PRINTER
  2692.                CMP     AL,PRINTER_CNT
  2693.                JA      NEXT_PRINTER
  2694.  
  2695. GOT_PRINTER:   MOV     MODIFY_FLAG,1
  2696.                MOV     DI,CX
  2697.                MOV     BP,AX
  2698.                CALL    WRITE_SCREEN
  2699. P_END1:        CALL    HIDE_CURSOR
  2700.                CALL    CK_MODIFIED
  2701.                JC      P_END
  2702.                MOV     AX,BP
  2703.                SUB     AL,"1"
  2704.  
  2705.                PUSH    ES
  2706.                MOV     ES,PGM_BUFF_SEG
  2707.                MOV     DI,LPT_ADDR
  2708.                STOSB
  2709.                POP     ES
  2710.                CALL    SAVE
  2711.  
  2712. P_END:         RET
  2713.  
  2714. ;--------------;
  2715. PRINTER_BASE   EQU     8
  2716.  
  2717. COUNT_PRINTERS:PUSH    DS
  2718.                MOV     AX,40H
  2719.                MOV     DS,AX
  2720.                MOV     AL,"0"
  2721.                MOV     SI,PRINTER_BASE
  2722.                MOV     AH,3
  2723.  
  2724. NEXT_PRINTERS: CMP     WORD PTR [SI],0
  2725.                JZ      PRINTERS_END
  2726.                INC     SI
  2727.                INC     SI
  2728.                INC     AL
  2729.                DEC     AH
  2730.                JNZ     NEXT_PRINTERS
  2731.  
  2732. PRINTERS_END:  POP     DS
  2733.                MOV     PRINTER_CNT,AL
  2734.                RET
  2735.  
  2736. ;--------------;
  2737. T_MENU         LABEL   BYTE
  2738. DB "Select text description then press Enter to change text.             Esc to Exit",0
  2739.  
  2740. TEXT_M         DB      "Text descriptions",0
  2741.                DB      "~~~~~~~~~~~~~~~~~",0
  2742.  
  2743. TEXT_INDEX     DW      0
  2744.  
  2745. TEXT_MENU:     CMP     [TEXT_MENUS],INACTIVE
  2746.                JZ      T_MENU_END1
  2747.                CALL    TEXT_DEFAULT
  2748.                MOV     TEXT_INDEX,0
  2749.  
  2750. NEXT_T_MENU:   MOV     STATE,CUSTOM_TYPE
  2751.                MOV     SI,OFFSET T_MENU
  2752.                CALL    DISPLAY_MENU
  2753.  
  2754. NEXT_T_MENU2:  CALL    DISP_TEXT
  2755.                CALL    GETKEY
  2756.                JC      T_MENU_END
  2757.                CMP     AL,LEFT_SCAN
  2758.                JZ      T_MENU_END
  2759.  
  2760.                CMP     AH,CR
  2761.                JZ      DO_TEXT
  2762.                CMP     AL,RIGHT_SCAN
  2763.                JZ      DO_TEXT
  2764.  
  2765. CK_T_UP:       MOV     BX,TEXT_INDEX
  2766.                CMP     AL,UP_SCAN
  2767.                JNZ     CK_T_DN
  2768.                SUB     BX,2
  2769.                JC      NEXT_T_MENU2
  2770.                JMP     SHORT TEXT_UPDATE
  2771.  
  2772. CK_T_DN:       CMP     AL,DOWN_SCAN
  2773.                JNZ     NEXT_T_MENU2
  2774.                INC     BX
  2775.                INC     BX
  2776.                CMP     BX,TEXT_MAX * 2
  2777.                JAE     NEXT_T_MENU2
  2778.                CMP     TEXT_MENUS[BX],INACTIVE
  2779.                JZ      NEXT_T_MENU2
  2780. TEXT_UPDATE:   MOV     TEXT_INDEX,BX
  2781.                JMP     NEXT_T_MENU2
  2782.  
  2783. DO_TEXT:       CALL    TEXT_SELECT
  2784.                JMP     NEXT_T_MENU
  2785.  
  2786. T_MENU_END1:   CALL    BEEP
  2787. T_MENU_END:    CALL    CK_MODIFIED
  2788.                JC      T_M_END
  2789.                CALL    COPY_TEXT
  2790.                CALL    SAVE
  2791. T_M_END:       RET
  2792.  
  2793. ;--------------;
  2794. TEXT_DEFAULT:  PUSH    DS
  2795.                MOV     DS,PGM_BUFF_SEG
  2796.                XOR     BX,BX
  2797.                XOR     BP,BP
  2798. NEXT_T_DEFAULT:CMP     CS:[TEXT_MENUS.BX],INACTIVE
  2799.                JZ      T_DEFAULT_END
  2800.                MOV     SI,CS:[TEXT_ADDRS.BX]
  2801.                MOV     DI,OFFSET TEXT_EDIT
  2802.                ADD     DI,BP
  2803.                MOV     CX,CS:[TEXT_LENGTH.BX]
  2804.                CMP     CX,STRING_MAX
  2805.                JB      GET_DEF
  2806.                MOV     CX,STRING_MAX - 1
  2807. GET_DEF:       REP     MOVSB
  2808.                XOR     AL,AL
  2809.                STOSB
  2810.                ADD     BP,STRING_MAX
  2811.                INC     BX
  2812.                INC     BX
  2813.                CMP     BX,TEXT_MAX * 2
  2814.                JB      NEXT_T_DEFAULT
  2815. T_DEFAULT_END: POP     DS
  2816.                RET
  2817.  
  2818. ;--------------;
  2819. T_EDIT_ADDR    DW      ?
  2820.  
  2821. DISP_TEXT:     MOV     AX,TEXT_TOP
  2822.                CALL    CALC_ADDR
  2823.                ADD     DI,SELECT_START
  2824.                MOV     BH,COLOR.W
  2825.  
  2826.                PUSH    DI
  2827.                MOV     SI,OFFSET TEXT_M
  2828.                CALL    WRITE_STRING
  2829.                POP     DI
  2830.                ADD     DI,CRT_WIDTH
  2831.  
  2832.                PUSH    DI
  2833.                CALL    WRITE_STRING
  2834.                POP     DI
  2835.  
  2836. ;--------------;
  2837.                XOR     BP,BP
  2838.                MOV     T_EDIT_ADDR,OFFSET TEXT_EDIT
  2839. NEXT_TEXT_DES: MOV     SI,TEXT_MENUS[BP]
  2840.                CMP     SI,INACTIVE
  2841.                JZ      TEXT_DES_END
  2842.                ADD     DI,CRT_WIDTH
  2843.                PUSH    DI
  2844.  
  2845.                MOV     CX,STRING_MAX
  2846.                MOV     BH,COLOR.W
  2847.                CMP     TEXT_INDEX,BP
  2848.                JNZ     WRITE_DESC2
  2849.                MOV     BH,COLOR.C
  2850.                CMP     STATE,CUSTOM_TYPE
  2851.                JZ      WRITE_DESC2
  2852.                MOV     BH,COLOR.A
  2853.  
  2854. WRITE_DESC2:   PUSH    DS
  2855.                MOV     DS,ZIF_BUFF_SEG
  2856.                CALL    WRITE_LINE
  2857.                CALL    PAD_LINE
  2858.                POP     DS
  2859.  
  2860.                MOV     BH,COLOR.W
  2861.                MOV     SI,T_EDIT_ADDR
  2862.                MOV     CX,TEXT_LENGTH[BP]
  2863.                CALL    WRITE_LINE
  2864.                POP     DI
  2865.                ADD     T_EDIT_ADDR,STRING_MAX
  2866.                INC     BP
  2867.                INC     BP
  2868.                CMP     BP,TEXT_MAX * 2
  2869.                JB      NEXT_TEXT_DES
  2870.  
  2871. TEXT_DES_END:  RET
  2872.  
  2873. ;----------------------------------------------;
  2874. TEXT_M2        LABEL   BYTE
  2875. DB "Edit text then press Enter.                                        Esc to cancel",0
  2876.  
  2877. TEXT_SELECT:   MOV     STATE,SELECT_TYPE
  2878.                CALL    DISP_TEXT
  2879.                MOV     SI,OFFSET TEXT_M2
  2880.                CALL    DISPLAY_MENU
  2881.  
  2882.                MOV     AX,TEXT_INDEX
  2883.                MOV     BX,AX
  2884.                MOV     CX,TEXT_LENGTH[BX]
  2885.                SHR     AX,1
  2886.                ADD     AX,TEXT_TOP + 2
  2887.                MUL     CRT_WIDTH
  2888.                ADD     AX,SELECT_START + (STRING_MAX * 2)
  2889.                MOV     SCREEN_START,AX
  2890.  
  2891.                MOV     AX,STRING_MAX
  2892.                SHR     BX,1
  2893.                MUL     BX
  2894.                ADD     AX,OFFSET TEXT_EDIT
  2895.                MOV     LINE_START,AX
  2896.                ADD     AX,CX
  2897.                MOV     LINE_END,AX
  2898.                MOV     BH,COLOR.C
  2899.                MOV     LEGAL_CHARS,OFFSET ALL_CHARS
  2900.                CALL    EDITOR
  2901.                JC      TEXT_S_END
  2902.                MOV     MODIFY_FLAG,TRUE
  2903. TEXT_S_END:    RET
  2904.  
  2905. ;----------------------------------------------;
  2906. COPY_TEXT:     PUSH    ES
  2907.                MOV     ES,PGM_BUFF_SEG
  2908.                XOR     BX,BX
  2909.                MOV     BP,OFFSET TEXT_EDIT
  2910. NEXT_T_COPY:   CMP     TEXT_MENUS[BX],INACTIVE
  2911.                JZ      COPY_T_END
  2912.                MOV     SI,BP
  2913.                MOV     DI,TEXT_ADDRS[BX]
  2914.                MOV     CX,TEXT_LENGTH[BX]
  2915.                REP     MOVSB
  2916.                INC     BX
  2917.                INC     BX
  2918.                ADD     BP,STRING_MAX
  2919.                JMP     NEXT_T_COPY
  2920.  
  2921. COPY_T_END:    POP     ES
  2922.                RET
  2923.  
  2924. ;--------------;
  2925. N_MENU         LABEL   BYTE
  2926. DB "Select number description then press Enter to change number.         Esc to Exit",0
  2927.  
  2928. NUMBER_M       DB      "Number descriptions",0
  2929.                DB      "~~~~~~~~~~~~~~~~~~~",0
  2930.  
  2931. NUMBER_INDEX   DW      0
  2932.  
  2933. NUMBER_MENU:   CMP     [NUMBER_MENUS],INACTIVE
  2934.                JZ      N_MENU_END1
  2935.                CALL    NUM_DEFAULT
  2936.                MOV     NUMBER_INDEX,0
  2937.  
  2938. NEXT_N_MENU:   MOV     STATE,CUSTOM_TYPE
  2939.                MOV     SI,OFFSET N_MENU
  2940.                CALL    DISPLAY_MENU
  2941.  
  2942. NEXT_N_MENU2:  CALL    DISP_NUMBERS
  2943.                CALL    GETKEY
  2944.                JC      N_MENU_END
  2945.                CMP     AL,LEFT_SCAN
  2946.                JZ      N_MENU_END
  2947.  
  2948.                CMP     AH,CR
  2949.                JZ      DO_NUM
  2950.                CMP     AL,RIGHT_SCAN
  2951.                JZ      DO_NUM
  2952.  
  2953. CK_N_UP:       MOV     BX,NUMBER_INDEX
  2954.                CMP     AL,UP_SCAN
  2955.                JNZ     CK_N_DN
  2956.                SUB     BX,2
  2957.                JC      NEXT_N_MENU2
  2958.                JMP     SHORT NUM_UPDATE
  2959.  
  2960. CK_N_DN:       CMP     AL,DOWN_SCAN
  2961.                JNZ     NEXT_N_MENU2
  2962.                INC     BX
  2963.                INC     BX
  2964.                CMP     BX,NUM_MAX * 2
  2965.                JAE     NEXT_N_MENU2
  2966.                CMP     NUMBER_MENUS[BX],INACTIVE
  2967.                JZ      NEXT_N_MENU2
  2968. NUM_UPDATE:    MOV     NUMBER_INDEX,BX
  2969.                JMP     NEXT_N_MENU2
  2970.  
  2971. DO_NUM:        CALL    NUMBER_SELECT
  2972.                JMP     NEXT_N_MENU
  2973.  
  2974. N_MENU_END1:   CALL    BEEP
  2975. N_MENU_END:    CALL    CK_MODIFIED
  2976.                JC      N_M_END
  2977.                CALL    COPY_NUMBERS
  2978.                CALL    SAVE
  2979. N_M_END:       RET
  2980.  
  2981. ;----------------------------------------------;
  2982. NUM_DEFAULT:   PUSH    DS
  2983.                MOV     DS,PGM_BUFF_SEG
  2984.                XOR     BX,BX
  2985.                MOV     BP,OFFSET NUMBER_EDIT
  2986. NEXT_N_DEFAULT:CMP     CS:[NUMBER_MENUS.BX],INACTIVE
  2987.                JZ      N_DEFAULT_END
  2988.                MOV     SI,CS:[NUMBER_ADDRS.BX]
  2989.                MOV     AX,[SI]
  2990.                CMP     BYTE PTR CS:[NUMBER_TYPE.BX],"W"
  2991.                JZ      GOT_NUM_VAL
  2992.                XOR     AH,AH
  2993.  
  2994. GOT_NUM_VAL:   MOV     DI,BP
  2995.                CALL    DECIMAL_ASCII
  2996.                ADD     BP,INTEGER_MAX
  2997.                INC     BX
  2998.                INC     BX
  2999.                CMP     BX,NUM_MAX * 2
  3000.                JB      NEXT_N_DEFAULT
  3001. N_DEFAULT_END: POP     DS
  3002.                RET
  3003.  
  3004. ;----------------------------------------------;
  3005. DECIMAL_ASCII: PUSH    BX
  3006.                MOV     BX,10                   ;Divisor of ten.
  3007.                XOR     CX,CX                   ;Zero in counter.
  3008. NEXT_COUNT:    XOR     DX,DX                   ;Zero in high half.
  3009.                DIV     BX                      ;Divide by ten.
  3010.                ADD     DL,"0"                  ;Convert to ASCII.
  3011.                PUSH    DX                      ;Save results.
  3012.                INC     CX                      ;Also increment count.
  3013.                OR      AX,AX                   ;Are we done?
  3014.                JNZ     NEXT_COUNT              ;Continue until zero.
  3015.                MOV     SI,INTEGER_MAX - 1
  3016.                SUB     SI,CX
  3017. NEXT_DEC_STORE:POP     AX                      ;Retrieve numbers.
  3018.                STOSB
  3019.                LOOP    NEXT_DEC_STORE
  3020.                MOV     CX,SI
  3021.                JCXZ    DEC_END
  3022.                MOV     AL,SPACE
  3023.                REP     STOSB
  3024. DEC_END:       XOR     AL,AL
  3025.                STOSB
  3026.                POP     BX
  3027.                RET
  3028.  
  3029. ;----------------------------------------------;
  3030. N_EDIT_ADDR    DW      ?
  3031.  
  3032. DISP_NUMBERS:  MOV     AX,NUMBER_TOP
  3033.                CALL    CALC_ADDR
  3034.                ADD     DI,SELECT_START
  3035.                MOV     BH,COLOR.W
  3036.  
  3037.                PUSH    DI
  3038.                MOV     SI,OFFSET NUMBER_M
  3039.                CALL    WRITE_STRING
  3040.                POP     DI
  3041.                ADD     DI,CRT_WIDTH
  3042.  
  3043.                PUSH    DI
  3044.                CALL    WRITE_STRING
  3045.                POP     DI
  3046.  
  3047. ;--------------;
  3048.                XOR     BP,BP
  3049.                MOV     N_EDIT_ADDR,OFFSET NUMBER_EDIT
  3050. NEXT_NUM_DES:  MOV     SI,NUMBER_MENUS[BP]
  3051.                CMP     SI,INACTIVE
  3052.                JZ      NUM_DES_END
  3053.                ADD     DI,CRT_WIDTH
  3054.                PUSH    DI
  3055.  
  3056.                MOV     BH,COLOR.W
  3057.                CMP     NUMBER_INDEX,BP
  3058.                JNZ     WRITE_DESC3
  3059.                MOV     BH,COLOR.C
  3060.                CMP     STATE,CUSTOM_TYPE
  3061.                JZ      WRITE_DESC3
  3062.                MOV     BH,COLOR.A
  3063.  
  3064. WRITE_DESC3:   PUSH    DS
  3065.                MOV     DS,ZIF_BUFF_SEG
  3066.                MOV     CX,STRING_MAX
  3067.                CALL    WRITE_LINE
  3068.                CALL    PAD_LINE
  3069.                POP     DS
  3070.  
  3071.                MOV     BH,COLOR.W
  3072.                MOV     SI,N_EDIT_ADDR
  3073.                CALL    WRITE_STRING
  3074.                POP     DI
  3075.                ADD     N_EDIT_ADDR,INTEGER_MAX
  3076.                INC     BP
  3077.                INC     BP
  3078.                CMP     BP,NUM_MAX * 2
  3079.                JB      NEXT_NUM_DES
  3080.  
  3081. NUM_DES_END:   RET
  3082.  
  3083. ;----------------------------------------------;
  3084. NUMBER_M2      LABEL   BYTE
  3085. DB "Enter number between "
  3086. RANGE_L        EQU     $ - NUMBER_M2
  3087. DB                      "                                              Esc to cancel",0
  3088.  
  3089. NUMBER_SELECT: MOV     STATE,SELECT_TYPE
  3090.                CALL    DISP_NUMBERS
  3091.                CALL    MENU_OFFSET
  3092.                MOV     BH,COLOR.B
  3093.                PUSH    DI
  3094.                MOV     SI,OFFSET NUMBER_M2
  3095.                CALL    WRITE_STRING
  3096.  
  3097.                MOV     BP,NUMBER_INDEX
  3098.                MOV     AX,RANGE_LOW[BP]
  3099.                MOV     DI,OFFSET NUMBER_RANGE
  3100.                CALL    DECIMAL_ASCII
  3101.                POP     DI
  3102.                ADD     DI,RANGE_L * 2
  3103.                MOV     SI,OFFSET NUMBER_RANGE
  3104. NEXT_RANGE:    LODSB
  3105.                CMP     AL,SPACE
  3106.                JA      NEXT_RANGE
  3107.                MOV     BYTE PTR [SI-1],0
  3108.                MOV     SI,OFFSET NUMBER_RANGE
  3109.                CALL    WRITE_STRING
  3110.                MOV     AL,"-"
  3111.                CALL    WRITE_SCREEN
  3112.                PUSH    DI
  3113.                MOV     AX,RANGE_HIGH[BP]
  3114.                MOV     DI,OFFSET NUMBER_RANGE
  3115.                CALL    DECIMAL_ASCII
  3116.                POP     DI
  3117.                MOV     SI,OFFSET NUMBER_RANGE
  3118.                CALL    WRITE_STRING
  3119.  
  3120.                MOV     AX,NUMBER_INDEX
  3121.                MOV     BX,AX
  3122.                SHR     AX,1
  3123.                ADD     AX,NUMBER_TOP + 2
  3124.                MUL     CRT_WIDTH
  3125.                ADD     AX,SELECT_START + (STRING_MAX * 2)
  3126.                MOV     SCREEN_START,AX
  3127.  
  3128.                MOV     AX,INTEGER_MAX
  3129.                SHR     BX,1
  3130.                MUL     BX
  3131.                ADD     AX,OFFSET NUMBER_EDIT
  3132.                MOV     LINE_START,AX
  3133.                ADD     AX,INTEGER_MAX - 1
  3134.                MOV     LINE_END,AX
  3135.                MOV     BH,COLOR.C
  3136.                MOV     LEGAL_CHARS,OFFSET NUMBER_CHARS
  3137.                CALL    EDITOR
  3138.                JC      NUM_S_END
  3139.  
  3140.                MOV     SI,LINE_START
  3141.                CALL    PARSE_LINE
  3142.                JC      NUM_S_END2
  3143.                CALL    GET_NUMBER
  3144.                JC      NUMBER_ERROR
  3145.                MOV     BP,NUMBER_INDEX
  3146.                CMP     AX,RANGE_LOW[BP]
  3147.                JB      NUMBER_ERROR
  3148.                CMP     AX,RANGE_HIGH[BP]
  3149.                JA      NUMBER_ERROR
  3150.  
  3151. NUM_S_END2:    MOV     MODIFY_FLAG,TRUE
  3152. NUM_S_END:     RET
  3153.  
  3154. NUMBER_ERROR:  MOV     SI,OFFSET NUMBER_ERR
  3155.                CALL    BACKUP_ERR2
  3156.                PUSH    DS
  3157.                MOV     BX,NUMBER_INDEX
  3158.                MOV     SI,DS:[NUMBER_ADDRS.BX]
  3159.                MOV     DS,PGM_BUFF_SEG
  3160.                MOV     AX,[SI]
  3161.                POP     DS
  3162.                CMP     BYTE PTR [NUMBER_TYPE.BX],"W"
  3163.                JZ      RESTORE_NUM
  3164.                XOR     AH,AH
  3165. RESTORE_NUM:   MOV     DI,LINE_START
  3166.                CALL    DECIMAL_ASCII
  3167.                JMP     NUM_S_END
  3168.  
  3169. ;----------------------------------------------;
  3170. COPY_NUMBERS:  PUSH    ES
  3171.                MOV     ES,PGM_BUFF_SEG
  3172.                XOR     BX,BX
  3173.                MOV     BP,OFFSET NUMBER_EDIT
  3174. NEXT_N_COPY:   CMP     NUMBER_MENUS[BX],INACTIVE
  3175.                JZ      COPY_N_END
  3176.                MOV     SI,BP
  3177.                CALL    PARSE_LINE
  3178.                JC      LOOP_N_COPY
  3179.                CALL    GET_NUMBER
  3180.                JC      LOOP_N_COPY
  3181.                MOV     DI,NUMBER_ADDRS[BX]
  3182.                CMP     BYTE PTR NUMBER_TYPE[BX],"W"
  3183.                JZ      COPY_WORD
  3184.                STOSB
  3185.                JMP     SHORT LOOP_N_COPY
  3186. COPY_WORD:     STOSW
  3187. LOOP_N_COPY:   INC     BX
  3188.                INC     BX
  3189.                ADD     BP,INTEGER_MAX
  3190.                JMP     NEXT_N_COPY
  3191.  
  3192. COPY_N_END:    POP     ES
  3193.                RET
  3194.  
  3195. ;----------------------------------------------;
  3196. DISP_CUSTOM:   MOV     AX,LISTING_TOP
  3197.                CALL    CALC_ADDR
  3198.                ADD     DI,CUSTOM_START
  3199.                MOV     SI,OFFSET CATEGORY + SIZE CAT
  3200.                MOV     BP,LISTING_LEN
  3201.  
  3202. NEXT_CUSTOM:   PUSH    SI
  3203.                PUSH    DI
  3204.                MOV     CX,CRT_WIDTH
  3205.                SUB     CX,CUSTOM_START
  3206.                SHR     CX,1
  3207.  
  3208.                CMP     SI,OFFSET CAT_END
  3209.                JAE     PAD_CUSTOM
  3210.                CMP     [SI.CAT_STATUS],INACTIVE
  3211.                JZ      GET_INACTIVE
  3212.  
  3213.                CMP     SI,CUSTOM_ADDR
  3214.                JNZ     CK_CUST_COLOR
  3215.                MOV     BH,COLOR.C
  3216.                CMP     STATE,FILE_TYPE
  3217.                JZ      DISPLAY_CUST
  3218.                MOV     BH,COLOR.A
  3219.                JMP     SHORT DISPLAY_CUST
  3220.  
  3221. CK_CUST_COLOR: MOV     BH,COLOR.I
  3222.                CMP     STATE,LISTING_TYPE
  3223.                JNZ     DISPLAY_CUST
  3224.                MOV     BH,COLOR.W
  3225.                JMP     SHORT DISPLAY_CUST
  3226.  
  3227. GET_INACTIVE:  MOV     BH,COLOR.T
  3228.                CMP     SI,CUSTOM_ADDR
  3229.                JZ      DISPLAY_CUST
  3230.                MOV     BH,COLOR.S
  3231.  
  3232. DISPLAY_CUST:  ADD     SI,SIZE CAT_STATUS + SIZE CAT_LEN
  3233.                MOV     AL,"["
  3234.                CALL    WRITE_CHAR
  3235.                DEC     CX
  3236.                CALL    WRITE_LINE
  3237.                MOV     BH,COLOR.W
  3238.                CALL    PAD_LINE
  3239.  
  3240. CK_LAST_CUST:  POP     DI
  3241.                POP     SI
  3242.                ADD     DI,CRT_WIDTH
  3243.                CMP     SI,OFFSET CAT_END
  3244.                JAE     LOOP_CUST
  3245.                ADD     SI,SIZE CAT
  3246.  
  3247. LOOP_CUST:     DEC     BP
  3248.                JNZ     NEXT_CUSTOM
  3249.                RET
  3250.  
  3251. PAD_CUSTOM:    MOV     BH,COLOR.W
  3252.                CALL    PAD_LINE
  3253.                JMP     SHORT CK_LAST_CUST
  3254.  
  3255. ;----------------------------------------------;
  3256. TOP_WINDOW     LABEL   BYTE
  3257. DB "╔════════════════════════════════════════╗",0
  3258. WINDOW_LEN     EQU     $ - TOP_WINDOW
  3259. BOTTOM_WINDOW  LABEL   BYTE
  3260. DB "╚════════════════════════════════════════╝",0
  3261.  
  3262. MODIFY_MENU    LABEL   BYTE
  3263. DB "║ Do you wish to save your changes?  Y/N ║",0
  3264.  
  3265. BACKUP_MENU    LABEL   BYTE
  3266. DB "║     Backup up program first?  Y/N      ║",0
  3267.  
  3268. OVERWRITE_MENU LABEL   BYTE
  3269. DB "║  Backup file exists.  Overwrite?  Y/N  ║",0
  3270.  
  3271. DISK_FULL_MENU  LABEL   BYTE
  3272. DB "║ Not enough disk space.  Press any key. ║",0
  3273.  
  3274. BACKUP_FAIL    LABEL   BYTE
  3275. DB "║     Backup failed.  Press any key.     ║",0
  3276.  
  3277. SAVE_FAIL      LABEL   BYTE
  3278. DB "║      Save failed.  Press any key.      ║",0
  3279.  
  3280. NUMBER_ERR     LABEL   BYTE
  3281. DB "║  Number out of range.  Press any key.  ║",0
  3282.  
  3283. CK_MODIFIED:   CMP     MODIFY_FLAG,TRUE
  3284.                JNZ     NO_MODIFY
  3285.                MOV     MODIFY_FLAG,FALSE
  3286.  
  3287. NEXT_MODIFY:   MOV     SI,OFFSET MODIFY_MENU
  3288.                CALL    DISP_WINDOW
  3289.  
  3290.                CALL    CLEAR_KEY
  3291.                CALL    GETKEY
  3292.                CMP     AL,ESC_SCAN
  3293.                JZ      NO_MODIFY
  3294.                CMP     AL,N_SCAN
  3295.                JZ      NO_MODIFY
  3296.                CMP     AL,Y_SCAN
  3297.                JNZ     NEXT_MODIFY
  3298.  
  3299. CK_BACKUP:     CMP     BACKUP_FLAG,TRUE
  3300.                JZ      YES_MODIFY
  3301.                MOV     SI,OFFSET BACKUP_MENU
  3302.                CALL    DISP_WINDOW
  3303.                CALL    CLEAR_KEY
  3304. GET_MODIFY:    CALL    GETKEY
  3305.                CMP     AL,ESC_SCAN
  3306.                JZ      NO_MODIFY
  3307.                CMP     AL,N_SCAN
  3308.                JZ      YES_MODIFY
  3309.                CMP     AL,Y_SCAN
  3310.                JNZ     GET_MODIFY
  3311.  
  3312.                CALL    DO_BACKUP
  3313.                JC      NEXT_MODIFY
  3314.  
  3315. YES_MODIFY:    CALL    CLEAR_MODIFIED
  3316.                CLC
  3317.                JMP     SHORT MODIFIED_END
  3318.  
  3319. NO_MODIFY:     CALL    CLEAR_MODIFIED
  3320.                STC
  3321.  
  3322. MODIFIED_END:  RET
  3323.  
  3324. ;----------------------------------------------;
  3325. ; OUTPUT: CF=1 if failed.
  3326.  
  3327. READ_HANDLE    DW      ?
  3328. WRITE_HANDLE   DW      ?
  3329.  
  3330. DO_BACKUP:     CALL    MAKE_BACKUP
  3331.                MOV     DX,OFFSET BACKUP_NAME
  3332.                XOR     CX,CX
  3333.                MOV     AH,4EH
  3334.                INT     21H
  3335.                JNC     OVERWRITE
  3336.  
  3337.                CALL    GET_FREE
  3338.                JNC     FREE_SPACE2
  3339.                JMP     BACKUP_END
  3340.  
  3341. OVERWRITE:     MOV     SI,OFFSET OVERWRITE_MENU
  3342.                CALL    DISP_WINDOW
  3343.                CALL    CLEAR_KEY
  3344.                CALL    GETKEY
  3345.                CMP     AL,Y_SCAN
  3346.                JZ      GET_DISK
  3347.                CMP     AL,ESC_SCAN
  3348.                JNZ     CK_OVER2
  3349.                STC
  3350.                JMP     BACKUP_END2
  3351. CK_OVER2:      CMP     AL,N_SCAN
  3352.                JNZ     OVERWRITE
  3353.                JMP     BACKUP_END
  3354.  
  3355. GET_DISK:      CALL    GET_FREE
  3356.                JNC     FREE_SPACE
  3357.                JMP     BACKUP_ERR
  3358. FREE_SPACE:    ADD     AX,DTA.SIZE_LOW
  3359.                ADC     DX,DTA.SIZE_HIGH
  3360. FREE_SPACE2:   SUB     AX,FILE_SIZE[0]
  3361.                SBB     DX,FILE_SIZE[2]
  3362.                JNC     CREATE
  3363.                MOV     SI,OFFSET DISK_FULL_MENU
  3364.                JMP     SHORT BACKUP_ERR2
  3365.  
  3366. CREATE:        MOV     DX,OFFSET BACKUP_NAME
  3367.                XOR     CX,CX
  3368.                MOV     AH,3CH
  3369.                INT     21H
  3370.                JNC     DO_BACKUP2
  3371.                JMP     SHORT BACKUP_ERR
  3372.  
  3373. DO_BACKUP2:    MOV     WRITE_HANDLE,AX
  3374.                MOV     DX,OFFSET ASCIIZ_NAME
  3375.                MOV     AX,3D00H
  3376.                INT     21H
  3377.                JC      CLOSE_READ
  3378.                MOV     READ_HANDLE,AX
  3379.  
  3380.                XOR     DX,DX
  3381. NEXT_BACKUP:   MOV     BX,READ_HANDLE
  3382.                MOV     CX,BAC_BUFF_SIZE * KILOBYTES - 1
  3383.                PUSH    DS
  3384.                MOV     DS,BAC_BUFF_SEG
  3385.                MOV     AH,3FH
  3386.                INT     21H
  3387.                POP     DS
  3388.                JC      CLOSE_READ
  3389.                OR      AX,AX
  3390.                JZ      CLOSE_READ
  3391.  
  3392.                MOV     CX,AX
  3393.                MOV     BX,WRITE_HANDLE
  3394.                PUSH    DS
  3395.                MOV     DS,BAC_BUFF_SEG
  3396.                MOV     AH,40H
  3397.                INT     21H
  3398.                POP     DS
  3399.                JC      CLOSE_READ
  3400.                CMP     CX,AX
  3401.                STC
  3402.                JNZ     CLOSE_READ
  3403.                CMP     CX,BAC_BUFF_SIZE * KILOBYTES - 1
  3404.                JZ      NEXT_BACKUP
  3405.                CLC
  3406.  
  3407. CLOSE_READ:    PUSHF
  3408.                MOV     BX,READ_HANDLE
  3409.                MOV     AH,3EH
  3410.                INT     21H
  3411.                POPF
  3412.  
  3413. CLOSE_WRITE:   PUSHF
  3414.                MOV     BX,WRITE_HANDLE
  3415.                MOV     AH,3EH
  3416.                INT     21H
  3417.                POPF
  3418.  
  3419.                JC      BACKUP_ERR
  3420.  
  3421. BACKUP_END:    MOV     BACKUP_FLAG,TRUE
  3422.                CALL    CLEAR_MODIFIED
  3423.                MOV     FAIL_FLAG,FALSE
  3424.                CLC
  3425. BACKUP_END2:   RET
  3426.  
  3427. BACKUP_ERR:    MOV     SI,OFFSET BACKUP_FAIL
  3428. BACKUP_ERR2:   CALL    DISP_WINDOW
  3429.                CALL    BEEP
  3430.                CALL    GETKEY
  3431.                CALL    CLEAR_MODIFIED
  3432.                MOV     FAIL_FLAG,FALSE
  3433.                STC
  3434.                RET
  3435.  
  3436. ;----------------------------------------------;
  3437. GET_FREE:      MOV     DL,PGM_DRIVE
  3438.                INC     DL
  3439.                MOV     AH,36H                  ;Disk free space.
  3440.                INT     21H
  3441.                CMP     AX,-1
  3442.                STC
  3443.                JZ      DISK_FREE_END
  3444.                MUL     BX                      ;Sectors per cluster * clusters
  3445.                PUSH    DX
  3446.                MUL     CX                      ;Result times bytes per cluster
  3447.                MOV     BX,AX
  3448.                POP     AX
  3449.                PUSH    DX
  3450.                MUL     CX
  3451.                POP     DX
  3452.                ADD     DX,AX
  3453.                MOV     AX,BX
  3454.                CLC
  3455. DISK_FREE_END: RET                             ; = available bytes.
  3456.  
  3457. ;----------------------------------------------;
  3458. BAK            DB      ".BAK",0
  3459.  
  3460. MAKE_BACKUP:   MOV     SI,OFFSET ASCIIZ_NAME
  3461.                MOV     DI,OFFSET BACKUP_NAME
  3462.                MOV     CX,8
  3463. NEXT_BACK:     LODSB
  3464.                CMP     AL,"."
  3465.                JZ      BAK_EXT
  3466.                OR      AL,AL
  3467.                JZ      BAK_EXT
  3468.                STOSB
  3469.                LOOP    NEXT_BACK
  3470. BAK_EXT:       MOV     SI,OFFSET BAK
  3471.                MOV     CX,5
  3472.                REP     MOVSB
  3473.                RET
  3474.  
  3475. ;----------------------------------------------;
  3476. ; INPUT: SI-> window.
  3477.  
  3478. DISP_WINDOW:   CALL    CALC_WIN
  3479.                MOV     BH,COLOR.W
  3480.                PUSH    DI
  3481.                PUSH    SI
  3482.                MOV     SI,OFFSET TOP_WINDOW
  3483.                CALL    WRITE_STRING
  3484.                POP     SI
  3485.                POP     DI
  3486.                ADD     DI,CRT_WIDTH
  3487.                PUSH    DI
  3488.                CALL    WRITE_STRING
  3489.                POP     DI
  3490.                ADD     DI,CRT_WIDTH
  3491.                MOV     SI,OFFSET BOTTOM_WINDOW
  3492.                CALL    WRITE_STRING
  3493.                RET
  3494.  
  3495. ;----------------------------------------------;
  3496. CLEAR_MODIFIED:CALL    CALC_WIN
  3497.                MOV     BH,COLOR.W
  3498.                MOV     AL,SPACE
  3499.                MOV     SI,3
  3500. NEXT_CLEAR_M:  PUSH    DI
  3501.                MOV     CX,WINDOW_LEN
  3502.                CALL    REPEAT_CHAR
  3503.                POP     DI
  3504.                ADD     DI,CRT_WIDTH
  3505.                DEC     SI
  3506.                JNZ     NEXT_CLEAR_M
  3507.                RET
  3508.  
  3509. ;----------------------------------------------;
  3510. CALC_WIN:      MOV     AL,ROWS
  3511.                DEC     AL
  3512.                DEC     AL
  3513.                DEC     AL
  3514.                XOR     AH,AH
  3515.                CALL    CALC_ADDR
  3516.                ADD     DI,SELECT_START
  3517.                RET
  3518.  
  3519. ;----------------------------------------------;
  3520. SAVE:          CALL    MAKE_FILENAME
  3521.                MOV     DX,OFFSET ASCIIZ_NAME
  3522.                MOV     AX,3D01H
  3523.                INT     21H
  3524.                JC      SAVE_ERR
  3525.                CMP     FAIL_FLAG,TRUE
  3526.                JZ      SAVE_ERR
  3527.  
  3528.                MOV     BX,AX
  3529.                MOV     CX,PGM_BYTES
  3530.                XOR     DX,DX
  3531.                PUSH    DS
  3532.                MOV     DS,PGM_BUFF_SEG
  3533.                MOV     AH,40H
  3534.                INT     21H
  3535.                POP     DS
  3536.  
  3537.                PUSHF
  3538.                MOV     AH,3EH
  3539.                INT     21H
  3540.                POPF
  3541.                JNC     SAVE_END
  3542.  
  3543. SAVE_ERR:      MOV     SI,OFFSET SAVE_FAIL
  3544.                CALL    DISP_WINDOW
  3545.                CALL    BEEP
  3546.                CALL    GETKEY
  3547.                CALL    CLEAR_MODIFIED
  3548.                STC
  3549.  
  3550. SAVE_END:      MOV     FAIL_FLAG,FALSE
  3551.                RET
  3552.  
  3553. ;----------------------------------------------;
  3554. CLEAR_FILE:    PUSH    ES
  3555.                PUSH    DI
  3556.  
  3557.                MOV     AX,LISTING_TOP
  3558.                CALL    CALC_ADDR
  3559.                ADD     DI,CUSTOM_START
  3560.                MOV     BP,LISTING_LEN
  3561.                MOV     DX,STATUS_REG           ;Retrieve status register.
  3562.                MOV     ES,VIDEO_SEG
  3563.                MOV     BH,COLOR.W
  3564.                MOV     AL,SPACE
  3565.  
  3566. NEXT_CLEAR:    PUSH    DI
  3567.                MOV     CX,CRT_WIDTH
  3568.                SUB     CX,CUSTOM_START
  3569.                SHR     CX,1
  3570. NEXT_CLEAR2:   CALL    WRITE_CHAR
  3571.                LOOP    NEXT_CLEAR2
  3572.                POP     DI
  3573.                ADD     DI,CRT_WIDTH
  3574.                DEC     BP
  3575.                JNZ     NEXT_CLEAR
  3576.  
  3577.                POP     DI
  3578.                POP     ES
  3579.                RET
  3580.  
  3581. ;--------------------------------------------------------------;
  3582. ; OUTPUT: ASCIIZ_NAME = filename
  3583.  
  3584. MAKE_ZIF_NAME: PUSH    DS
  3585.                MOV     SI,BAR_ADDR
  3586.                MOV     DS,FILENAME_SEG         ;DS:SI -> Source name.
  3587.                MOV     DI,OFFSET ASCIIZ_NAME   ;Name storage.
  3588.                MOV     CX,8                    ;8 characters of name.
  3589. NEXT_NAME2:    LODSB
  3590.                CMP     AL,SPACE                ;End of name?
  3591.                JZ      EXTENSION3              ;If yes, do extension.
  3592.                STOSB
  3593.                LOOP    NEXT_NAME2
  3594.  
  3595. EXTENSION3:    POP     DS
  3596.                MOV     SI,OFFSET ZIF_EXT
  3597.                MOV     CX,ZIF_LEN
  3598.                REP     MOVSB
  3599.                RET
  3600.  
  3601. ;----------------------------------------------;
  3602.  
  3603. MAKE_FILENAME: PUSH    DS
  3604.                MOV     SI,BAR_ADDR
  3605.                MOV     DS,FILENAME_SEG         ;DS:SI -> Source name.
  3606.                MOV     BP,SI
  3607.                MOV     DI,OFFSET ASCIIZ_NAME   ;Name storage.
  3608.                MOV     CX,8                    ;8 characters of name.
  3609. NEXT_NAME:     LODSB
  3610.                CMP     AL,SPACE                ;End of name?
  3611.                JZ      EXTENSION2              ;If yes, do extension.
  3612.                STOSB
  3613.                LOOP    NEXT_NAME
  3614. EXTENSION2:    MOV     SI,BP                   ;Retrieve name start.
  3615.                ADD     SI,9                    ;Move to extension field.
  3616.                CMP     BYTE PTR [SI],SPACE     ;Is there any extension?
  3617.                JZ      NAME_DONE               ;If no, done.
  3618.                MOV     AL,"."                  ;Else, add delimiting dot.
  3619.                STOSB
  3620.                MOV     CX,3                    ;3 characters for extension.
  3621. NEXT_EXT:      LODSB
  3622.                CMP     AL,SPACE
  3623.                JZ      NAME_DONE
  3624.                STOSB
  3625.                LOOP    NEXT_EXT
  3626. NAME_DONE:     XOR     AL,AL                   ;ASCIIZ.
  3627.                STOSB
  3628.                POP     DS
  3629.                RET
  3630.  
  3631. ;----------------------------------------------;
  3632. DISP_LISTING:  PUSH    DS
  3633.                PUSH    ES
  3634.  
  3635.                MOV     AX,LISTING_TOP
  3636.                CALL    CALC_ADDR
  3637.                MOV     SI,LISTING_ADDR
  3638.                MOV     BP,LISTING_LEN
  3639.                MOV     DX,STATUS_REG           ;Retrieve status register.
  3640.                MOV     ES,VIDEO_SEG            ;Point to screen segment.
  3641.                MOV     DS,FILENAME_SEG
  3642.  
  3643. NEXT_LISTING:  PUSH    DI
  3644.                MOV     CX,SIZE FILE_RECORD
  3645.  
  3646. DISPLAY_LINE:  MOV     BH,CS:COLOR.I
  3647.                CMP     BYTE PTR [SI],-1
  3648.                JZ      PAD_LISTING
  3649.                CMP     SI,CS:BAR_ADDR
  3650.                JZ      CK_BAR_COLOR
  3651.                CMP     CS:STATE,FILE_TYPE
  3652.                JNZ     DISPLAY_LINE2
  3653.                MOV     BH,CS:COLOR.W
  3654.                JMP     SHORT DISPLAY_LINE2
  3655.  
  3656. CK_BAR_COLOR:  MOV     BH,CS:COLOR.C
  3657.                CMP     CS:STATE,FILE_TYPE
  3658.                JNZ     DISPLAY_LINE2
  3659.                MOV     BH,CS:COLOR.A
  3660.  
  3661. DISPLAY_LINE2: LODSB
  3662.                CALL    WRITE_CHAR
  3663.                LOOP    DISPLAY_LINE2
  3664.  
  3665. CK_LAST_LINE:  POP     DI
  3666.                ADD     DI,CS:CRT_WIDTH
  3667.                DEC     BP
  3668.                JNZ     NEXT_LISTING
  3669.                POP     ES
  3670.                POP     DS
  3671.                RET
  3672.  
  3673. PAD_LISTING:   CALL    PAD_LINE
  3674.                JMP     SHORT CK_LAST_LINE
  3675.  
  3676.  
  3677. ;--------------;
  3678. PAD_LINE:      JCXZ    PAD_LINE_END
  3679.                MOV     AL,SPACE
  3680. PAD_LINE2:     CALL    WRITE_CHAR
  3681.                LOOP    PAD_LINE2
  3682. PAD_LINE_END:  RET
  3683.  
  3684. ;----------------------------------------------;
  3685. ; Keeps track of a variable length field in CX while writing string.
  3686. WRITE_LINE:    LODSB
  3687.                OR      AL,AL
  3688.                JZ      WRITE_LINE_END
  3689.                CALL    WRITE_CHAR
  3690.                LOOP    WRITE_LINE
  3691. WRITE_LINE_END:RET
  3692.  
  3693. ;--------------;
  3694. DUMMY_RET:     RET
  3695.  
  3696. ;----------------------------------------------;
  3697. ZIF_DIR_MENU   DB      "    Zif Directory is     ",0
  3698. PGM_DIR_MENU   DB      "    Utility Directory is ",0
  3699. HEADING        DB      "Utilities   ",0,"Custom Categories",0
  3700.                DB      "~~~~~~~~~   ",0,"~~~~~~~~~~~~~~~~~",0
  3701.  
  3702. DISP_DIR:      MOV     BH,COLOR.B
  3703.                MOV     DI,CRT_WIDTH
  3704.                MOV     CX,DI
  3705.                SHR     CX,1
  3706.  
  3707.                PUSH    DI
  3708.                MOV     SI,OFFSET ZIF_DIR_MENU
  3709.                CALL    WRITE_LINE
  3710.                MOV     AL,ZIF_DRIVE
  3711.                ADD     AL,"A"
  3712.                CALL    WRITE_CHAR
  3713.                DEC     CX
  3714.                MOV     AL,":"
  3715.                CALL    WRITE_CHAR
  3716.                DEC     CX
  3717.                MOV     SI,OFFSET ZIF_DIR
  3718.                CALL    WRITE_LINE
  3719.                CALL    PAD_LINE
  3720.  
  3721.                POP     DI
  3722.                MOV     CX,CRT_WIDTH
  3723.                ADD     DI,CX
  3724.                PUSH    DI
  3725.                SHR     CX,1
  3726.                MOV     SI,OFFSET PGM_DIR_MENU
  3727.                CALL    WRITE_LINE
  3728.                MOV     AL,PGM_DRIVE
  3729.                ADD     AL,"A"
  3730.                CALL    WRITE_CHAR
  3731.                DEC     CX
  3732.                MOV     AL,":"
  3733.                CALL    WRITE_CHAR
  3734.                DEC     CX
  3735.                MOV     SI,OFFSET PGM_DIR
  3736.                CALL    WRITE_LINE
  3737.                CALL    PAD_LINE
  3738.                POP     DI
  3739.  
  3740.                MOV     CX,CRT_WIDTH
  3741.                ADD     DI,CX
  3742.                SHR     CX,1
  3743.                PUSH    DI
  3744.                MOV     BH,COLOR.W
  3745.                MOV     SI,OFFSET HEADING
  3746.                CALL    WRITE_LINE
  3747.                INC     DI
  3748.                INC     DI
  3749.                DEC     CX
  3750.                CALL    WRITE_LINE
  3751.                CALL    PAD_LINE
  3752.                POP     DI
  3753.  
  3754.                MOV     CX,CRT_WIDTH
  3755.                ADD     DI,CX
  3756.                SHR     CX,1
  3757.                CALL    WRITE_LINE
  3758.                INC     DI
  3759.                INC     DI
  3760.                DEC     CX
  3761.                CALL    WRITE_LINE
  3762.                CALL    PAD_LINE
  3763.  
  3764.                RET
  3765.  
  3766. ;---------------------------------------------------;
  3767. ; Insertion sort;  Doesn't destroy secondary sorts. ;
  3768. ;---------------------------------------------------;
  3769. SORT:          MOV     BP,LAST_ADDR
  3770.                XOR     SI,SI                   ;SI = First record.
  3771.                MOV     DI,SIZE FILE_RECORD     ;DI = Second record.
  3772.                PUSH    DS
  3773.                PUSH    ES
  3774.                MOV     ES,FILENAME_SEG
  3775.                MOV     DS,FILENAME_SEG
  3776.  
  3777.                CMP     BYTE PTR [SI],-1
  3778.                JZ      SORT_END
  3779.                CMP     BYTE PTR [DI],-1
  3780.                JZ      SORT_END
  3781.  
  3782. NEXT_SORT:     CMP     DI,BP                   ;Sort is done when last record.
  3783.                JA      SORT_END
  3784.  
  3785.                PUSH    SI                      ;Save record pointers.
  3786.                PUSH    DI
  3787.                MOV     AX,SI                   ;Carry source pointer in AX.
  3788.                MOV     DX,DI                   ;Carry destination pointer in DX.
  3789.  
  3790. NEXT_RECORD:   MOV     CX,SIZE FILE_RECORD     ;Field length.
  3791. COMPARE:       REPZ    CMPSB                   ;Compare the fields.
  3792.                JBE     NO_SWITCH               ;If below or equal, no switch.
  3793.  
  3794. SWAP:          CMP     DX,TEMP_RECORD          ;Else, if DX points to temporary
  3795.                JZ      DO_SWAP                 ; storage, safe to move.
  3796.                MOV     SI,DX                   ;Else, move destination record
  3797.                MOV     DX,TEMP_RECORD          ; to temporary storage.
  3798.                MOV     DI,DX
  3799.                MOV     CX,SIZE FILE_RECORD / 2
  3800.                REP     MOVSW
  3801.  
  3802. DO_SWAP:       MOV     SI,AX                   ;Restore source pointer
  3803.                MOV     DI,SI                   ;Destination = source +
  3804.                ADD     DI,SIZE FILE_RECORD     ; field size.
  3805.                MOV     CX,SIZE FILE_RECORD / 2
  3806.                REP     MOVSW                   ;Move the record.
  3807.  
  3808.                MOV     DI,DX                   ;Prepare for next compare.
  3809.                SUB     AX,SIZE FILE_RECORD     ;Destination = temporary.
  3810.                MOV     SI,AX                   ;Move one record towards start.
  3811.                JNC     NEXT_RECORD
  3812.  
  3813. NO_SWITCH:     MOV     SI,TEMP_RECORD          ;If DX doesn't point to temporary
  3814.                CMP     DX,SI                   ; storage, no move was made; next
  3815.                JNZ     NEXT_INSERT             ; compare.
  3816.                MOV     DI,AX                   ;Else, move temporary record
  3817.                ADD     DI,SIZE FILE_RECORD     ; into last move location.
  3818.                MOV     CX,SIZE FILE_RECORD / 2
  3819.                REP     MOVSW
  3820.  
  3821. NEXT_INSERT:   POP     DI                      ;Restore outside loop pointers.
  3822.                POP     SI
  3823.                ADD     SI,SIZE FILE_RECORD     ;Move both source and destination
  3824.                ADD     DI,SIZE FILE_RECORD     ; to the next record.
  3825.                JMP     NEXT_SORT
  3826.  
  3827. SORT_END:      POP     ES
  3828.                POP     DS
  3829.                MOV     FILE_CURRENT,FALSE
  3830.                RET
  3831.  
  3832. ;----------------------------------------------;
  3833. ; OUTPUT: CF=1 if illegal parameter; DX-> illegal parameter.
  3834.  
  3835. PARSE:         MOV     SI,81H
  3836.                MOV     DI,OFFSET ZIF_DRIVE
  3837.                CALL    PARSE_IT
  3838.                CALL    RESTORE_DIR
  3839.                CALL    PARSE_DELIMIT
  3840.                CMP     BYTE PTR [SI],SPACE
  3841.                JA      PARSE_PGM
  3842. COPY_ZIF:      MOV     SI,OFFSET ZIF_DRIVE
  3843.                MOV     DI,OFFSET PGM_DRIVE
  3844.                MOV     CX,SPEC_SIZE
  3845.                REP     MOVSB
  3846.                CLC
  3847.                JMP     SHORT PARSE_END
  3848.  
  3849. PARSE_PGM:     CMP     BYTE PTR [SI],";"
  3850.                JNZ     PARSE_PGM2
  3851.                INC     SI
  3852. PARSE_PGM2:    MOV     DI,OFFSET PGM_DRIVE
  3853.                CALL    PARSE_IT
  3854.                JC      COPY_ZIF
  3855. PARSE_END:     RET
  3856.  
  3857. ;----------------------------------------------;
  3858. ; INPUT:  SI-> parameter; DI-> storage.
  3859. ; OUTPUT: CF=1 if illegal parameter; DX-> illegal parameter; SI-> parameter end.
  3860.  
  3861. PARSE_IT:      CALL    PARSE_DELIMIT
  3862.                MOV     BX,SI                   ;Filespec start.
  3863. NEXT_PARSE:    LODSB
  3864.                CMP     AL,";"
  3865.                JZ      PARSE_DRIVE
  3866.                CMP     AL,","
  3867.                JZ      PARSE_DRIVE
  3868.                CMP     AL,"/"
  3869.                JZ      PARSE_DRIVE
  3870.                CMP     AL,SPACE
  3871.                JBE     PARSE_DRIVE
  3872.                CMP     AL,":"
  3873.                JNZ     NEXT_PARSE
  3874.                MOV     DL,[SI-2]
  3875.                AND     DL,5FH                  ;Capitalize.
  3876.                SUB     DL,"A"                  ;Convert to DOS format.
  3877.                CALL    SELECT_DISK
  3878.                MOV     BX,SI                   ;Save as filename start.
  3879.                JMP     NEXT_PARSE              ;Continue parsing.
  3880.  
  3881. PARSE_DRIVE:   MOV     AH,19H
  3882.                INT     21H
  3883.                STOSB
  3884.                PUSH    SI
  3885.                MOV     SI,OFFSET CURRENT_DIR
  3886.                CALL    GET_DIR
  3887.                POP     SI
  3888.  
  3889.                DEC     SI
  3890.                CMP     SI,BX
  3891.                JZ      PARSE_DIR
  3892.                PUSH    [SI]
  3893.                MOV     BYTE PTR [SI],0
  3894.                MOV     DX,BX
  3895.                CALL    CHANGE_DIR
  3896.                POP     [SI]
  3897.  
  3898. PARSE_DIR:     PUSHF
  3899.                PUSH    SI
  3900.                MOV     SI,DI
  3901.                CALL    GET_DIR
  3902.                POP     SI
  3903.                POPF
  3904.  
  3905. PARSE_DIR_END: MOV     DX,BX
  3906.                RET
  3907.  
  3908. ;-----------------------------------------------------------------;
  3909. ; INPUT: SI -> string;  OUTPUT SI -> first non-white space.       ;
  3910. ;-----------------------------------------------------------------;
  3911. PARSE_DELIMIT:
  3912. NEXT_DELIMIT:  LODSB                           ;Get a byte.
  3913.                OR      AL,AL
  3914.                JZ      LEADING_END2
  3915.                CMP     AL,CR
  3916.                JZ      LEADING_END2
  3917.                CMP     AL,SPACE                ;Is it a space char or below?
  3918.                JBE     NEXT_DELIMIT
  3919. LEADING_END2:  DEC     SI                      ;Else, adjust pointer to
  3920.                RET                             ; string start.
  3921.  
  3922. ;----------------------------------------------;
  3923. PARSE_LINES:   CALL    PARSE_LINE
  3924.                JNC     PARSE_LINE_END
  3925.                CMP     AL,LF
  3926.                JZ      PARSE_LINES
  3927.                JMP     SHORT NO_PARA2
  3928.  
  3929. PARSE_LINE:    LODSB
  3930.                CMP     AL,CTRL_Z
  3931.                JZ      NO_PARA
  3932.                CMP     AL,"["
  3933.                JZ      NO_PARA
  3934.                CMP     AL,LF
  3935.                JZ      NO_PARA2
  3936.                CMP     AL,SPACE
  3937.                JBE     PARSE_LINE
  3938.                CMP     AL,"="
  3939.                JZ      PARSE_LINE
  3940.                CMP     AL,";"
  3941.                JZ      COMMENTS
  3942.  
  3943.                CLC
  3944.                DEC     SI
  3945. PARSE_LINE_END:RET
  3946.  
  3947. COMMENTS:      LODSB
  3948.                CMP     AL,CTRL_Z
  3949.                JZ      NO_PARA
  3950.                CMP     AL,LF
  3951.                JZ      NO_PARA2
  3952.                JMP     COMMENTS
  3953.  
  3954. NO_PARA:       DEC     SI
  3955. NO_PARA2:      STC
  3956.                RET
  3957.  
  3958. ;----------------------------------------------;
  3959. ; INPUT: SI -> ASCII number.
  3960. ; OUTPUT: CF=1 if no number.  CX:AX = number.
  3961.  
  3962. NUM_FLAG       DB      ?
  3963.  
  3964. GET_NUMBER:    PUSH    SI
  3965. NEXT_CAP2:     LODSB
  3966.                CMP     AL,SPACE
  3967.                JBE     GET_TYPE
  3968.                CMP     AL,"a"
  3969.                JB      NEXT_CAP2
  3970.                CMP     AL,"z"
  3971.                JA      NEXT_CAP2
  3972.                AND     BYTE PTR [SI-1],5FH
  3973.                JMP     NEXT_CAP2
  3974.  
  3975. GET_TYPE:      POP     SI
  3976.                PUSH    SI
  3977. NEXT_TYPE:     LODSB
  3978.                CMP     AL,SPACE
  3979.                JBE     A_NUMBER
  3980.                CMP     AL,"A"
  3981.                JB      NEXT_TYPE
  3982.                CMP     AL,"H"
  3983.                JA      NEXT_TYPE
  3984.                POP     SI
  3985.                CALL    DO_HEX
  3986.                JMP     SHORT NUMBER_END
  3987.  
  3988. A_NUMBER:      POP     SI
  3989.                CALL    DO_NUMBER
  3990.  
  3991. NUMBER_END:    RET
  3992.  
  3993. ;--------------;
  3994. DO_HEX:        PUSH    BX
  3995.                XOR     BX,BX                   ;Start with zero.
  3996.                XOR     CX,CX
  3997.                MOV     CS:NUM_FLAG,0           ;Number exists flag.
  3998.  
  3999. NEXT_HEX:      LODSB                           ;Get a byte.
  4000.                CMP     AL,CTRL_Z
  4001.                JZ      HEX_END1
  4002.                CMP     AL,"H"
  4003.                JZ      HEX_END2
  4004.                CMP     AL,COMMA
  4005.                JZ      NEXT_HEX
  4006.                CMP     AL,"-"
  4007.                JZ      HEX_END2
  4008.                CMP     AL,SPACE
  4009.                JBE     HEX_END2
  4010.                SUB     AL,"0"                  ;ASCII to binary.
  4011.                JC      HEX_ERR                 ;If not 0 to 9, skip.
  4012.                CMP     AL,9                    ;Is it A - F ?
  4013.                JLE     NOT_ALPHA               ;If no, OK.
  4014.                SUB     AL,7                    ;Else, adjust for alpha.
  4015.                CMP     AL,10                   ;Is it punctuation?
  4016.                JB      HEX_END2                ;If yes, skip.
  4017.                CMP     AL,15                   ;Is it valid?
  4018.                JA      HEX_ERR                 ;If no, skip.
  4019. NOT_ALPHA:     MOV     AH,4
  4020. NEXT_SHIFT2:   SHL     BX,1
  4021.                RCL     CX,1
  4022.                DEC     AH
  4023.                JNZ     NEXT_SHIFT2
  4024.                OR      BL,AL                   ;Add to number.
  4025.                MOV     CS:NUM_FLAG,1
  4026.                JMP     NEXT_HEX
  4027. HEX_END1:      DEC     SI
  4028. HEX_END2:      MOV     AX,BX
  4029.                CMP     CS:NUM_FLAG,0
  4030.                JZ      HEX_ERR
  4031.                CLC
  4032. HEX_END:       POP     BX
  4033.                RET
  4034.  
  4035. HEX_ERR:       STC
  4036.                POP     BX
  4037.                RET
  4038.  
  4039. ;--------------;
  4040. DO_NUMBER:     PUSH    BX
  4041.                PUSH    BP
  4042.                XOR     BX,BX                   ;Start with zero.
  4043.                XOR     CX,CX
  4044.                MOV     CS:NUM_FLAG,0           ;Number exists flag.
  4045.                MOV     BP,10
  4046. NEXT_NUMBER:   LODSB
  4047.                XOR     AH,AH                   ;Zero in high half.
  4048.                CMP     AL,CTRL_Z
  4049.                JZ      NUM_END1
  4050.                CMP     AL,COMMA
  4051.                JZ      NEXT_NUMBER
  4052.                CMP     AL,"-"
  4053.                JZ      NUM_END2
  4054.                CMP     AL,SPACE                ;Is byte a carriage return?
  4055.                JBE     NUM_END2                ;If yes, done.
  4056.                CMP     AL,COMMA
  4057.                JZ      NEXT_NUMBER
  4058.                CMP     AL,"0"                  ;Is byte a number?
  4059.                JB      NUM_ERR
  4060.                CMP     AL,"9"
  4061.                JA      NUM_ERR                ;If no, done.
  4062.                SUB     AL,"0"                  ;Else, convert to hex.
  4063.                XCHG    AX,BX                   ;Store in BX.
  4064.                MUL     BP                      ;Multiply accumulated by 10.
  4065.                PUSH    DX
  4066.                XCHG    AX,CX
  4067.                MUL     BP
  4068.                ADD     BX,CX
  4069.                POP     CX
  4070.                ADC     CX,0
  4071.                ADD     CX,AX
  4072.                MOV     CS:NUM_FLAG,1            ;Flag number found.
  4073.                JMP     NEXT_NUMBER
  4074.  
  4075. NUM_END1:      DEC     SI
  4076. NUM_END2:      MOV     AX,BX
  4077.                CMP     CS:NUM_FLAG,0
  4078.                JZ      NUM_ERR
  4079.                CLC
  4080. NUM_END:       POP     BP
  4081.                POP     BX
  4082.                RET
  4083.  
  4084. NUM_ERR:       STC
  4085.                POP     BP
  4086.                POP     BX
  4087.                RET
  4088.  
  4089. ;----------------------------------------------;
  4090. VIDEO_SETUP:   PUSH    ES
  4091.                MOV     AX,500H                 ;Make sure active page is zero.
  4092.                INT     10H
  4093.                MOV     AX,40H                  ;Point to the ROM BIOS data area
  4094.                MOV     ES,AX
  4095.                MOV     AX,ES:CRT_COLS
  4096.                MOV     COLUMNS,AX
  4097.                SHL     AX,1
  4098.                MOV     CRT_WIDTH,AX
  4099.                MOV     AX,ES:[4EH]
  4100.                MOV     CRT_START,AX
  4101.  
  4102.                MOV     AX,ES:[63H]
  4103.                ADD     AX,6
  4104.                MOV     CX,0B000H
  4105.                CMP     AX,3BAH
  4106.                JZ      STORE_SEG
  4107.                ADD     CX,800H
  4108. STORE_SEG:     MOV     STATUS_REG,AX
  4109.                MOV     VIDEO_SEG,CX
  4110.  
  4111.                MOV     SI,OFFSET MONO_ATTR
  4112.                MOV     AL,ES:CRT_MODE          ;Retrieve current video mode.
  4113.                CMP     AL,7                    ;Is it mono mode?
  4114.                JZ      GET_ROWS                ;If yes, continue.
  4115.                CMP     AL,2                    ;Is it BW80?
  4116.                JZ      GET_ROWS                ;If yes, continue.
  4117.                MOV     SI,OFFSET COLOR_ATTR
  4118.                CMP     AL,3                    ;Is it mode CO80?
  4119.                JZ      GET_ROWS                ;If yes, continue.
  4120.                MOV     AX,3                    ;Else, change video mode to CO80.
  4121.                INT     10H
  4122.  
  4123. GET_ROWS:      XOR     BH,BH
  4124.                MOV     DL,24
  4125.                MOV     AX,1130H
  4126.                INT     10H
  4127.                MOV     ROWS,DL                 ;Store rows.
  4128.                SUB     DL,MENU_LINES - 1
  4129.                XOR     DH,DH
  4130.                MOV     LISTING_LEN,DX
  4131.  
  4132.                POP     ES
  4133.                MOV     DI,OFFSET COLOR
  4134.                MOV     CX,SIZE COLOR_ATTRIBS
  4135.                REP     MOVSB
  4136.  
  4137. ;----------------------------------------------;
  4138.  
  4139. DISPLAY_SETUP: CALL    CLS                     ;Clear screen.
  4140.  
  4141.                CMP     BORDER_FLAG,1
  4142.                JZ      DO_COPYRIGHT
  4143.                MOV     BL,COLOR.W              ;Turn on border.
  4144.                AND     BL,7
  4145.                XOR     BH,BH
  4146.                MOV     AH,0BH
  4147.                INT     10H
  4148.  
  4149. DO_COPYRIGHT:  XOR     AX,AX
  4150.                CALL    CALC_ADDR
  4151.                INC     DI
  4152.                INC     DI
  4153.                MOV     SI,OFFSET COPYRIGHT     ;Point to copyright message.
  4154.                MOV     BH,COLOR.B              ;Use header attribute.
  4155.                CALL    WRITE_STRING            ;And display it.
  4156.                RET
  4157.  
  4158. ;----------------------------------------------;
  4159. ; INPUT: SI-> menu.
  4160.  
  4161. DISPLAY_MENU:  CALL    MENU_OFFSET
  4162.                MOV     BH,COLOR.B
  4163.                CALL    WRITE_STRING
  4164.                RET
  4165.  
  4166. ;*************LINE EDITOR**********************;
  4167.  
  4168. LINE_START     DW      ?
  4169. LINE_END       DW      ?
  4170. SCREEN_START   DW      ?
  4171.  
  4172. ;INPUT: BH=color; LINE_START=buffer position; LINE_END; SCREEN_START.
  4173. ;OUTPUT: CY=1 if Esc pressed.
  4174.  
  4175. EDITOR:        MOV     DI,LINE_START
  4176.                CALL    EDIT_CURSOR
  4177.                CALL    DISP_EDIT
  4178. EDITOR2:       CALL    CK_KEY
  4179.                JZ      EDITOR2
  4180.                OR      AL,AL
  4181.                JZ      NEXT_EDIT
  4182.                CMP     AL,CR
  4183.                JZ      NEXT_EDIT
  4184.                CMP     AH,ESC_SCAN
  4185.                JZ      NEXT_EDIT
  4186.  
  4187.                MOV     CX,LINE_END
  4188.                SUB     CX,LINE_START
  4189.                PUSH    DI
  4190.                MOV     AL,SPACE
  4191.                REP     STOSB
  4192.                POP     DI
  4193.  
  4194. NEXT_EDIT:     CALL    EDIT_CURSOR
  4195.                CALL    DISP_EDIT
  4196.                CALL    GETKEY
  4197.                XCHG    AL,AH
  4198. NEXT_EDIT2:    JNC     DO_EDIT
  4199.                JMP     EDITOR_END
  4200.  
  4201. DO_EDIT:       MOV     DX,LINE_START
  4202.                MOV     CX,LINE_END
  4203.  
  4204.                CMP     AH,ENTER_SCAN
  4205.                JNZ     CK_RIGHT
  4206.                JMP     EDITOR_DONE
  4207.  
  4208. CK_RIGHT:      CMP     AX,RIGHT_SCAN SHL 8
  4209.                JNZ     CK_LEFT
  4210.                CMP     DI,CX
  4211.                JZ      NEXT_EDIT
  4212.                INC     DI
  4213.  
  4214. CK_LEFT:       CMP     AX,LEFT_SCAN SHL 8
  4215.                JNZ     CK_BS
  4216.                CMP     DI,DX
  4217.                JZ      NEXT_EDIT
  4218.                DEC     DI
  4219.                JMP     NEXT_EDIT
  4220.  
  4221. CK_BS:         CMP     AH,BS_SCAN
  4222.                JNZ     CK_DEL
  4223.                CMP     DI,DX
  4224.                JZ      NEXT_EDIT
  4225.                DEC     DI
  4226.                CALL    CK_INSERT
  4227.                JNZ     DO_DEL1
  4228.                MOV     BYTE PTR [DI],SPACE
  4229.                JMP     NEXT_EDIT
  4230.  
  4231. CK_DEL:        CMP     AX,DEL_SCAN SHL 8
  4232.                JNZ     CK_HOME
  4233. DO_DEL1:       CALL    DO_DEL
  4234.                JMP     NEXT_EDIT
  4235.  
  4236. CK_HOME:       CMP     AX,HOME_SCAN SHL 8
  4237.                JNZ     CK_END2
  4238.                MOV     DI,DX
  4239.  
  4240. CK_END2:       CMP     AX,END_SCAN SHL 8
  4241.                JNZ     CK_ASCII
  4242.                MOV     DI,CX
  4243. NEXT_CK_END2:  CMP     DI,DX
  4244.                JZ      NEXT_EDIT
  4245.                CMP     BYTE PTR [DI-1],SPACE
  4246.                JNZ     NEXT_EDIT
  4247.                DEC     DI
  4248.                JMP     NEXT_CK_END2
  4249.  
  4250. CK_ASCII:      CALL    CK_LEGAL
  4251.                JC      NEXT_EDIT
  4252.                CMP     DI,CX
  4253.                JAE     NEXT_EDIT
  4254.                CALL    CK_INSERT
  4255.                JNZ     DO_INSERT
  4256.                STOSB
  4257.                JMP     NEXT_EDIT
  4258.  
  4259. DO_INSERT:     MOV     DX,DI
  4260.                DEC     CX
  4261.                MOV     DI,CX
  4262.                SUB     CX,DX
  4263.                JZ      DO_INSERT2
  4264.                MOV     SI,DI
  4265.                DEC     SI
  4266.                STD
  4267.                REP     MOVSB
  4268.                CLD
  4269. DO_INSERT2:    MOV     DI,DX
  4270.                STOSB
  4271.                JMP     NEXT_EDIT
  4272.  
  4273. EDITOR_DONE:   CLC
  4274. EDITOR_END:    PUSHF
  4275.                CALL    HIDE_CURSOR
  4276.                POPF
  4277.                RET
  4278.  
  4279. ;--------------;
  4280. LEGAL_CHARS    DW      ?
  4281.  
  4282. NUMBERS        DB      "1234567890abcdefhABCDEFH"
  4283. NUMBERS_LEN    EQU     $ - NUMBERS
  4284.  
  4285. CK_LEGAL:      CMP     AL,SPACE
  4286.                JB      ILLEGAL
  4287.                CMP     AL,127
  4288.                JA      ILLEGAL
  4289.                JMP     [LEGAL_CHARS]
  4290. NUMBER_CHARS:  PUSH    DI
  4291.                PUSH    CX
  4292.                MOV     DI,OFFSET NUMBERS
  4293.                MOV     CX,NUMBERS_LEN
  4294.                REPNZ   SCASB
  4295.                POP     CX
  4296.                POP     DI
  4297.                JNZ     ILLEGAL
  4298.  
  4299. ALL_CHARS:     CLC
  4300.                RET
  4301.  
  4302. ILLEGAL:       STC
  4303.                RET
  4304.  
  4305. ;--------------------------
  4306. DO_DEL:        PUSH    DI
  4307.                MOV     SI,DI
  4308.                INC     SI
  4309.                DEC     CX
  4310.                SUB     CX,DI
  4311.                JS      DEL_END
  4312.                REP     MOVSB
  4313.                MOV     BYTE PTR [DI],SPACE
  4314. DEL_END:       POP     DI
  4315.                RET
  4316.  
  4317. ;--------------------------
  4318.  
  4319. CK_INSERT:     PUSH    DS
  4320.                MOV     DX,40H
  4321.                MOV     DS,DX
  4322.                MOV     DL,DS:[17H]
  4323.                TEST    DL,80H                  ;Insert
  4324.                POP     DS
  4325.                RET
  4326.  
  4327. ;--------------------------
  4328. EDIT_CURSOR:   MOV     AX,SCREEN_START
  4329.                XOR     DX,DX
  4330.                DIV     CRT_WIDTH
  4331.                SHR     DL,1
  4332.                MOV     DH,AL
  4333.                MOV     AX,DI
  4334.                SUB     AX,LINE_START
  4335.                ADD     DL,AL
  4336.                CALL    SET_CURSOR
  4337.                RET
  4338.  
  4339. ;--------------------------
  4340. DISP_EDIT:     PUSH    DI
  4341.                MOV     DI,SCREEN_START
  4342.                MOV     SI,LINE_START
  4343.                CALL    WRITE_STRING
  4344.                POP     DI
  4345.                RET
  4346.  
  4347. ;----------------------------------------------;
  4348. ;INPUT: CX=char count; AX=character
  4349. REPEAT_CHAR:   PUSH    AX
  4350.                CALL    WRITE_SCREEN
  4351.                POP     AX
  4352.                LOOP    REPEAT_CHAR
  4353.                RET
  4354.  
  4355. ;----------------------------------------------;
  4356. ; INPUT: AX = Starting line; OUTPUT: DI = Video address.
  4357.  
  4358. CALC_ADDR:     MUL     CRT_WIDTH
  4359.                ADD     AX,CRT_START
  4360.                MOV     DI,AX
  4361.                RET
  4362.  
  4363. ;----------------------------------------------;
  4364. ; INPUT:  AL = character to write;  BH = attribute.
  4365.  
  4366. WRITE_SCREEN:  PUSH    ES
  4367.                MOV     ES,CS:VIDEO_SEG         ;Point to screen segment.
  4368.                MOV     DX,CS:STATUS_REG        ;Retrieve status register.
  4369.                MOV     BL,AL                   ;Store character in BL.
  4370.  
  4371. HORZ_RET:      IN      AL,DX                   ;Get status.
  4372.                RCR     AL,1                    ;Is it low?
  4373.                JC      HORZ_RET                ;If not, wait until it is.
  4374.                CLI                             ;No more interrupts.
  4375.  
  4376. HWAIT:         IN      AL,DX                   ;Get status.
  4377.                RCR     AL,1                    ;Is it high?
  4378.                JNC     HWAIT                   ;If no, wait until it is.
  4379.  
  4380.                MOV     AX,BX                   ;Retrieve character; now it's OK
  4381.                STOSW                           ; to write to screen buffer.
  4382.                STI                             ;Interrupts back on.
  4383.                POP     ES
  4384.                RET                             ;Return
  4385.  
  4386. ;----------------------------------------------;
  4387. ; INPUT:  AL=character to write;  BH=attribute.
  4388.  
  4389. WRITE_CHAR:    PUSH    ES
  4390.                MOV     DX,CS:STATUS_REG
  4391.                MOV     ES,CS:VIDEO_SEG
  4392.                MOV     BL,AL                   ;Store character in BL.
  4393.  
  4394. HORZ_RET2:     IN      AL,DX                   ;Get status.
  4395.                RCR     AL,1                    ;Is it low?
  4396.                JC      HORZ_RET2               ;If not, wait until it is.
  4397.                CLI                             ;No more interrupts.
  4398.  
  4399. HWAIT2:        IN      AL,DX                   ;Get status.
  4400.                RCR     AL,1                    ;Is it high?
  4401.                JNC     HWAIT2                  ;If no, wait until it is.
  4402.  
  4403.                MOV     AX,BX                   ;Retrieve character; now it's OK
  4404.                STOSW                           ; to write to screen buffer.
  4405.                STI                             ;Interrupts back on.
  4406.                POP     ES
  4407.                RET                             ;Return
  4408.  
  4409. ;----------------------------------------------;
  4410. ; INPUT:  SI -> to string to display;  DI -> where to display it.
  4411. ;   Entry point is WRITE_STRING.
  4412.  
  4413. WRITE_IT:      CALL    WRITE_SCREEN            ;Write a character.
  4414. WRITE_STRING:  LODSB                           ;Retrieve a character.
  4415.                CMP     AL,CR                   ;Keep writing until a carriage
  4416.                JA      WRITE_IT                ; return or zero encountered.
  4417.                RET
  4418.  
  4419. ;----------------------------------------------;
  4420. CLEAR_MENU:    CALL    MENU_OFFSET             ;Calculate menu screen offset.
  4421.                PUSH    DI
  4422.                MOV     BH,COLOR.B              ;Menu attribute.
  4423.                MOV     CX,CRT_WIDTH            ;Blank out the two lines of menu.
  4424.                SHR     CX,1
  4425. NEXT_MENU:     MOV     AL,SPACE
  4426.                CALL    WRITE_SCREEN
  4427.                LOOP    NEXT_MENU
  4428.                POP     DI
  4429.                RET
  4430.  
  4431. ;----------------------------------------;
  4432. ; OUTPUT: DI -> Screen offset for menu.  ;
  4433. ;----------------------------------------;
  4434. MENU_OFFSET:   MOV     AL,ROWS
  4435.                XOR     AH,AH
  4436.                CALL    CALC_ADDR
  4437.                RET
  4438.  
  4439. ;----------------------------------------------;
  4440. CLS:           MOV     BH,COLOR.B              ;Normal attribute.
  4441. CLS2:          XOR     CX,CX                   ;Top left corner.
  4442.                MOV     DL,BYTE PTR COLUMNS
  4443.                DEC     DL
  4444.                MOV     DH,ROWS
  4445.                MOV     AX,600H                 ;Scroll active page.
  4446.                PUSH    BP
  4447.                INT     10H
  4448.                POP     BP
  4449.                RET
  4450.  
  4451. ;----------------------------------------------;
  4452. CLOSE_SCREEN:  PUSH    AX
  4453.                MOV     BH,SCREEN_COLOR
  4454.                CALL    CLS2
  4455.  
  4456.                CMP     BORDER_FLAG,1
  4457.                JZ      PLACE_CURSOR
  4458.                XOR     BX,BX
  4459.                MOV     AH,0BH
  4460.                INT     10H
  4461.  
  4462. PLACE_CURSOR:  XOR     DX,DX
  4463.                CALL    SET_CURSOR
  4464.                POP     AX
  4465.                RET
  4466.  
  4467. ;----------------------------------------------;
  4468. BEEP:          MOV     BX,NOTE                 ;Tone frequency divisor.
  4469.                MOV     DX,12H
  4470.                XOR     AX,AX
  4471.                DIV     BX
  4472.                MOV     BX,AX                   ;8253 countdown.
  4473.  
  4474.                CALL    DELAY                   ;Wait till clock rolls over.
  4475.  
  4476.                MOV     AL,0B6H                 ;Channel 2 speaker functions.
  4477.                OUT     43H,AL                  ;8253 Mode Control.
  4478.                JMP     $+2                     ;IO delay.
  4479.                MOV     AX,BX                   ;Retrieve countdown.
  4480.                OUT     42H,AL                  ;Channel 2 LSB.
  4481.                JMP     $+2
  4482.                MOV     AL,AH                   ;Channel 2 MSB.
  4483.                OUT     42H,AL
  4484.                IN      AL,61H                  ;Port B.
  4485.                OR      AL,3                    ;Turn on speaker.
  4486.                JMP     $+2
  4487.                OUT     61H,AL
  4488.  
  4489.                CALL    DELAY                   ;Delay one second.
  4490.                IN      AL,61H                  ;Get Port B again.
  4491.                AND     AL,NOT 3                ;Turn speaker off.
  4492.                JMP     $+2
  4493.                OUT     61H,AL
  4494.                RET                             ;Done.
  4495.  
  4496. ;-----------------------------;
  4497. DELAY:         PUSH    DS                      ;Preserve data segment.
  4498.                MOV     AX,40H                  ;Point to BIOS data segment.
  4499.                MOV     DS,AX
  4500.                MOV     AX,DS:[6CH]             ;Retrieve timer low.
  4501. NEXT_BEEP:     MOV     DX,DS:[6CH]             ;Retrieve timer low.
  4502.                CMP     DX,AX                   ;Have we timed out?
  4503.                JZ      NEXT_BEEP               ;If not, wait until second up.
  4504.                POP     DS                      ;Restore data segment.
  4505.                RET
  4506.  
  4507. ;----------------------------------------------;
  4508. ; INPUT: SI-> DIR storage.
  4509.  
  4510. GET_DIR:       MOV     BYTE PTR [SI],"\"       ;DOS doesn't preface directory
  4511.                INC     SI                      ; with slash so we must.
  4512.                XOR     DL,DL
  4513.                MOV     AH,47H                  ;Get current directory.
  4514.                INT     21H
  4515.                RET
  4516.  
  4517. ;----------------------------------------------;
  4518. HIDE_CURSOR:   MOV     DH,ROWS                 ;Retrieve CRT rows.
  4519.                INC     DH                      ;Move one line below off screen.
  4520.                XOR     DL,DL                   ;Column zero.
  4521.  
  4522. SET_CURSOR:    PUSH    BX
  4523.                XOR     BH,BH                   ;Page zero.
  4524.                MOV     AH,2                    ;Set cursor position.
  4525.                INT     10H
  4526.                POP     BX
  4527.                RET
  4528.  
  4529. ;----------------------------------------------;
  4530. RESTORE_DIR:   MOV     DX,OFFSET CURRENT_DIR
  4531.                CALL    CHANGE_DIR
  4532.                MOV     DL,DEFAULT_DRIVE
  4533.                CALL    SELECT_DISK
  4534.                RET
  4535.  
  4536. ;----------------------------------------------;
  4537. SELECT_DISK:   MOV     AH,0EH
  4538.                INT     21H
  4539.                RET
  4540.  
  4541. ;----------------------------------------------;
  4542. CHANGE_DIR:    MOV     AH,3BH                  ;Change current directory.
  4543.                INT     21H
  4544.                RET
  4545.  
  4546. ;----------------------------------------------;
  4547. SET_ZIF:       CALL    RESTORE_DIR
  4548.                MOV     DL,ZIF_DRIVE
  4549.                CALL    SELECT_DISK
  4550.                MOV     SI,OFFSET CURRENT_DIR
  4551.                CALL    GET_DIR
  4552.                MOV     DX,OFFSET ZIF_DIR
  4553.                CALL    CHANGE_DIR
  4554.                RET
  4555.  
  4556. ;----------------------------------------------;
  4557. SET_PGM:       CALL    RESTORE_DIR
  4558.                MOV     DL,PGM_DRIVE
  4559.                CALL    SELECT_DISK
  4560.                MOV     SI,OFFSET CURRENT_DIR
  4561.                CALL    GET_DIR
  4562.                MOV     DX,OFFSET PGM_DIR
  4563.                CALL    CHANGE_DIR
  4564.                RET
  4565.  
  4566. ;----------------------------------------------;
  4567. ; INPUT:  AL=Scan code; AH=Char; DI -> Valid scan codes table; CX = Table length
  4568. ; OUTPUT: AL=Scan code; AH=Char.
  4569.  
  4570. DISPATCH:      PUSH    AX
  4571.                MOV     BX,CX
  4572.                MOV     DX,DI
  4573.                ADD     DX,CX
  4574.                REPNZ   SCASB
  4575.                JNZ     DISPATCH_END
  4576.  
  4577. GOT_DISPATCH:  SUB     BX,CX
  4578.                DEC     BX
  4579.                SHL     BX,1
  4580.                ADD     BX,DX
  4581.                CALL    GET_PARAMS
  4582.                CALL    [BX]                    ;Process the command.
  4583. DISPATCH_END:  POP     AX
  4584.                RET
  4585.  
  4586. ;----------------------------------------------;
  4587.  
  4588. GET_PARAMS:    MOV     AX,SIZE FILE_RECORD
  4589.                MUL     LISTING_LEN
  4590.                MOV     BP,BAR_ADDR
  4591.                MOV     DX,LISTING_ADDR
  4592.                MOV     CX,LAST_ADDR
  4593. PARAMS_END:    RET
  4594.  
  4595. ;----------------------------------------------;
  4596.  
  4597. GETKEY:        TEST    KBD_STATUS,80H
  4598.                JNZ     KEY_CLEAR
  4599.                CALL    CK_KEY
  4600.                JNZ     GETKEY2
  4601.                JMP     GETKEY
  4602.  
  4603. KEY_CLEAR:     CALL    CK_KEY
  4604.                JNZ     GETKEY2
  4605.                MOV     KBD_STATUS,0
  4606.                CMP     FILE_CURRENT,TRUE
  4607.                JZ      GETKEY
  4608.                CALL    DISP_FILE
  4609.                JMP     GETKEY
  4610.  
  4611. GETKEY2:       XOR     AH,AH                   ;Wait for next keyboard input.
  4612.                INT     16H
  4613.                XCHG    AH,AL
  4614.                CMP     AL,ESC_SCAN
  4615.                STC
  4616.                JZ      GETKEY_END
  4617.                CLC
  4618. GETKEY_END:    RET
  4619.  
  4620. CK_KEY:        MOV     AH,1                    ;Is there a keystroke available.
  4621.                INT     16H
  4622.                RET
  4623.  
  4624. CLEAR_IT:      XOR     AH,AH
  4625.                INT     16H                     ;Read keystrokes until buffer
  4626. CLEAR_KEY:     CALL    CK_KEY                  ; empty.
  4627.                JNZ     CLEAR_IT
  4628.                RET
  4629.  
  4630. ;----------------------------------------------;
  4631.  
  4632. WRITE_TTY:     MOV     AH,0EH
  4633.                INT     10H
  4634.                RET
  4635.  
  4636. ;----------------------------------------------;
  4637. PRINT_STRING:  MOV     AH,9                    ;Print string via DOS.
  4638.                INT     21H
  4639.                RET
  4640.  
  4641. ;----------------------------------------------;
  4642. OLD9           DW      ?,?
  4643.  
  4644. INSTALL_9:     PUSH    ES
  4645.                MOV     AX,3509H                ;INT 9
  4646.                INT     21H
  4647.                MOV     OLD9[0],BX
  4648.                MOV     OLD9[2],ES
  4649.                MOV     DX,OFFSET INT_9         ;Install new interrupt.
  4650.                MOV     AX,2509H
  4651.                INT     21H
  4652.                POP     ES
  4653.                RET
  4654.  
  4655. ;----------------------------------------------;
  4656. UNINSTALL_9:   PUSH    DS
  4657.                MOV     DX,OLD9[0]              ;Restore old INT 9.
  4658.                MOV     DS,OLD9[2]
  4659.                MOV     AX,2509H
  4660.                INT     21H
  4661.                POP     DS
  4662.                RET
  4663.  
  4664. ;----------------------------------------------;
  4665. INSTALL_24:    MOV     DX,OFFSET INT_24        ;Install new interrupt.
  4666.                MOV     AX,2524H
  4667.                INT     21H
  4668.                RET
  4669.  
  4670. EVEN
  4671. STACK_POINTER  =       $ + 256
  4672.  
  4673.  
  4674. _TEXT          ENDS
  4675.                END     START
  4676.